一、Es6提供了新的声明方式,替代了var
那么var的缺陷在哪里呢?
看下面的一段代码:
for(var i=0;i<10;i++){
console.log(i+"我的")//012345678910
}
console.log(i)//10
var不支持封闭作用域
以前有种方式可以封闭下这个作用域的(自调用函数),请看:
(function(){
for(var i=0;i<3;i++){
console.log(i)
}
})();
console.log(i) 这边就报错了
但是这样写代码很恶心,意思就是给他搞成函数作用域然后就变成私有的了
for(var i = 0;i<3;i++){
(function(i){
setTimeout(function(){
console.log(i)
},1000);
})(i)
}
这样异步的话,必须要写到自调用函数里面,然后把i传一下?具体我也不是很懂,有大佬可以留言,跪下来谢谢。
所以那么恶心心的var,es6就给了2哥们
1、let
首先let{ }配合起来就形成了封闭的作用域。
for(let i= 0;i<3;i++){
console.log(i)//0,1,2
}
console.log(i)//这里也是会报错的
let有唯一性,申明过的变量不可以重复申明。
var变量提升就是用let 去解决。
2、const
const定义的变量是不可以被修改的,不能被修改引用空间
比如:
const name = 1;
const name =2;
???????
这样就不好使了
二、解构赋值
先来个场景
咱们定义一个数组是吧,需要拿数组的每一项
let arr = ["范冰冰","19"];
let name = arr[0];
let age = arr[1];
console.log(name);
console.log(age)
这样是比较麻烦的,所以es6就给出了解构赋值
let [name,age,sex] = ["范冰冰",10,"女"];
console.log(name+","+age+","+sex)
不过需要注意:数组的位置必须相同
下面看个组件???????
let {name,age,sex:N} = {name:"狗不理包子",age:18,sex:"女"}
console.log(N)//女
关键字可以采用形式进行改名字
备注:对象结构时名字必须相同
下面再看个列子吧
let[,{address:[,a]},{sex:b}]=[{name:"黑马警长"},{age:9,address:[1,2,3]},{sex:"男"}];
console.log(a)//2
console.log(b)//男
解构赋值的方便之处,如果想设置某个属性的默认值 必须采用=的方式
来个函数的小列子吧
function eat(){
return ["韩信","李白","高丽丽"]
}
let [a,b,c] = eat();
console.log(a);
console.log(b);
console.log(c)
三、es6模板字符串
let name = "高老庄";
let address = "猪八戒";
let str = `${address}去${name}娶媳妇!`
console.log(str)
这个就是解决了恶心的字符串拼接问题。
案列: 实现一个类字符串模板的功能????
算了,不会写,哈啊啊啊啊啊啊啊啊
知识:Array.prototype.slice.call(arguments)的作用是将函数传入的参数转换为数组对象;
用这玩意的原因:这里需要注意的是typeof arguments打印出的是object,可以看出arguments并不是真正的数组,它是一个对象。
案列:给想要的地方加个*,跟有病似的。
let name = "周星驰";
age = 18;
function eat(){
let constant = arguments[0];//这里存的是常量
let values = [].slice.call(arguments,1)//这段的意思就是除了第一项,把后面都存到一个数组(Array.prototype与【】)
let str = ""//新建一个返回的字符串
for(let i =0;i<values.length;i++){
str+= `*${constant[i]}*${values[i]}*`
}
str += constant[constant.length-1]
return str
}
let str = eat`我是${name},今年${age}岁了`
console.log(str)
下面介绍一些常用方法
//includes是否包含????
返回一个布尔类型
let url = "https://www.4399.com";
console.log(url.includes("4399"));//true
console.log(url.includes("你是神经病么?"));//false
//startsWith以什么开头
返回的布尔类型
//endsWith以什么结尾
返回的布尔
//padStart padEnd 补全
padStart(len, str)
根据给定长度自动在字符串的前面补充想补充的字符串(只返回修改后的字符串,不修改原字符串)
len 给定的长度,转换后
str 想补充的字符串
四、箭头函数
//语法简单 可以解决this的问题
1、没有function关键字
2、一个参数是小括号能够省略
3、如果没有return的话,大括号也可以是省略
4、对象不是作用域,let声明也不会声明到全局上
5、没有this指向
6、箭头函数里面没有arguments
let fn = a => a;
console.log(fn(1))
7、剩余运算符
let gen = (x,...age) =>{
console.log(age)//[12345,6]
}
gen('x',12345,6)
大概的意思就是是将后面的剩余的部分编写到一个数组里
8、函数参数的默认值
//函数参数的默认值
let fn = (a=1,b=2) =>{
console.log(a,b)
}
fn()
五、展开运算符()
1、首先来看个骚操作
function spreed(x,...arg){
run.apply(null,arg)
}
function run(a,b,c,d){
console.log(a,b,c,d)
}
spreed("x",1,2,3,4)//直接把1234穿过去了
下面用展开运算符演示一哈
function spreed(x,...arg){
run(...arg)//展开运算符
}
function run(a,b,c,d,e){
console.log(a,b,c,d,e)
}
spreed("x",1,2,3,4,5)
2、数组的拼接
let ae4 = [1,2,3].concat([5,6,7]);
console.log(ae4)
用数组运算符展示一哈
let arr = [...[1,2,3],...[4,5,6]];
console.log(arr)//[1,2,3,4,5,6]
3、关于对象的使用合并
let name = {name:"生而为人"};
let age ={age:20};
let zero = {...name,...age};
console.log(zero)//{name: "生而为人", age: 20}
...这个带有浅拷贝
概念解读:
1、深拷贝:拷贝出2个完全不相同的东西,A的内容拷贝给B,修改B的值无法修改A的内容。
2、浅拷贝:拷贝出2个看起来相同的东西,A的内容拷贝给B,修改B的值是可以影响到A的内容的
let a = [1,2,3];
let b = [a];
let c = b.slice(0);
a[0] = 100;
console.log(c)
上述例子为浅拷贝,证明slice也是一个浅拷贝
那么我们怎么去实现一个深拷贝呢???
保留继承关系 可以实现各类型的拷贝 实现递归拷贝
//定义一个深拷贝的函数
function deepClone(t){
if(t ==null) return null;
if( typeof t !== Object) return t;
if (t instanceof Date) return new Date(t);
if(t instanceof RegExp) return new RegExp(t);
}
console.log(deepClone(22))
用递归去做深度拷贝,不太理解。
六、数组的常见方法
1、map、some、every、filter、forEach
2、find findIndex
3、reduce 收敛 叠加
4、for of ()
let arr = [1,2,3];
let red =(a,b)=>{
return a+b
}
let c = arr.reduce(red);
console.log(c)
let result = [1,2,3,4,5].reduce((a,b,c,d)=>{
console.log(a,b,c,d);
return a+b
})
上面我们可以清楚的看到每次返回的函数结果都是下一个的a;
看个东东吧
let total = [{price:10},{price:20},{price:50}].reduce((a,b,c,d)=>{
return a+b.price
},0)
console.log(total)
这个0就是保证a是0,不影响叠加,对就是怎么解释滴。
Array.prototype.remove = function(fn,t) {
for(let i= 0;i<this.length;i++){
fn(2)
}
};
[1,2,3].remove((t)=>{
console.log(t)
},20)
分号必须要加,不然就出问题了
map
let arr = [1,2,3].map(function(item){
return item*2
})
console.log(arr)
给每个代码乘以2
forEarch
[1,2,3,4,5,6].forEach((t)=>{
console.log(t)
});
正常来说是遍历数组,可这玩意的返回值是undefined跟map稍微有些不同
map功能的自行封装
Array.prototype.forMap = function(callback){
//为什么要新创键一个空数组??
let arr = [];
//因为创建一个新的空数组我们用for循坏去处理,然后返回他
for(let i = 0;i<this.length;i++){
arr.push(callback(this[i],i))//第一个this传的就是每一项,第二个i就是索引
}
return arr//返回一哈
};
let arr = [1,2,3].forMap((item)=>{
return item*3
})
console.log(arr)//[3,6,9]
filter过滤 如果返回true表示留下 返回false表示删除????具体啥意思哦哦
let arr = [1,2,3,4,5];
let a = arr.filter((item)=>{
return item>3
});
console.log(a)//[4,5]
目测返回的是大于3的数组哟
find查找
会返回查找的哪一项,找到后就停止落
let f = [1,2,3].find((t)=>{
return t === 2;
})
console.log(f)//2
let f = [1,2,3].find((t)=>{
return t === 5;
})
console.log(f)//undefined
some找到后返回true
let f = [1,2,3].some((t)=>{
return t === 5;
})
console.log(f)//false
every有一个不对那就返回false
let f = [1,2,3].every((t)=>{
return t === 1;
})
console.log(f)//false
includes意思就是是否包含?
let arr = [1,2,3,4].includes(3)
console.log(arr)//true
当我们想把类数组转化为数组的时候
Array.from();
join() 方法用于把数组中的所有元素放入一个字符串。
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。
下面科普一哈
function setm(){
let a = eval(Array.from(arguments).join("+"));
console.log(a)//6
};
setm(1,2,3);
相当于一个求和的功能趴
of
Array.of
七、对象
assign:这个也是浅拷贝
let obj1 ={name:"我好蠢"};
let obj2 = {age:10};
let arr = Object.assign(obj1,obj2)
console.log(arr)//{name: "我好蠢", age: 10}
跟扩展运算符的功能类似
//__proto__ 这个就是原型链
在es6中可以在对象内中可以直接操作__prot0__
let name = {name:"wang"};
let age = {age:10};
// name.__proto__ = age;//直接将name的原型指向age
Object.setPrototypeOf(name,age)//哈哈哈一毛一样哈
console.log(name.age)//现在就可以看到用name就可以取到age了
let obj = {
name:"jb",
age:18
};
let obj2 = {
__proto__ :obj,
getName(){
return super.name//可以通过super
}
}
console.log(obj2.getName())
getPrototypeof();
setPrototypeof();
很好用的原型链子
八、继承
1、如何实现一个类?
上个代码压压惊
unction Parent(){
this.name = "暴富";
}
Parent.prototype.eat = function(){
console.log("胖成猪了还吃啊?")
}
console.log(Parent.prototype.constructor === Parent)//实例原型的构造器是指向实例本身的
继承私有属性
function parent(){
this.name = "goj";
};
parent.prototype.eat = function(){
console.log("多吃点才能瘦");
};
function child(){
this.age = 10;
parent.call(this);//这个this就相当于this.name = "goj"
};
let aa = new child();
console.log(aa.name)
上述代码是将parent的name属性继承给了child,call在这里就是改变this指向的,呼呼呼
function Drink(){
this.name ="dsd";
};
Drink.prototype.eat = function(){
console.log("跟他爸一个德行!!");
};
function DrinkOrgin(){
this.age = 10;
};
//这里注意我们需要将父亲的原型等于儿子的原型
DrinkOrgin.prototype.__proto__ = Drink.prototype;
let arr = new DrinkOrgin()
arr.eat();
这个就是公共方法的继承呢
Object.create