数组的扩展
1.Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object:本质特征只有一点,即必须有length属性)和可遍历(iterable)的对象
实际应用中类似数组的对象式DOM操作返回的NodeList集合,以及函数内部的arguments对象,有点难以理解吧,请看实例
下面这张图片说明,字符串和Set结构都具有Iterator(可遍历)接口,因此可以被Array.from转化为真正的数组
对于还没有部署该方法的浏览器,可以用Array.prototype ,slice方法替代
Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,就昂处理后的值放入返回的数组
Array.from()的另一个应用是,将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种Unicode字符,可以避免js将大于\uFFFF的Unicode字符算作两个字符的bug
2、Array.of()
Array.of()方法用于将一组值,转换为数组
Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载
3、数组实例的copyWithin(),它的作用是将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组
它接收三个参数
-target 必需(从该诶之开始替换数据)
-start (可选):从该位置开始读取数据,默认为0,负数表示倒数
-end(可选):到该位置前停止读取数据,默认等于数组长度。
4、数组实例的find()和findIndex()
数组find()用于找出第一个符合条件的数组成员,它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined
find方法的回调函数可以接受三个参数,依次为当前的值value、当前的位置index和原数组arr
findIndex与find()方法非常类似,返回第一个符合条件的数组成员的位置,如果所有的成员都不符合条件,则返回-1
这两方法都可以发现NaN,弥补了数组的IndexOf方法的不足
5、数组的实例fill()
fill方法使用给定值,填充一个数组
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置
6、数组实例的entries、keys()、values()
这三个新的方法都返回一个遍历器对象,它们的区别keys()是对键名的遍历,entries()是对键值对的遍历,values是对键值的遍历
7、数组实例的includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似
没有该方法之前,我们通常使用数组的indexof方法,检查是否包含某个值。但是indexof有两个缺点,一是不够语义化,而是,它内部使用杨哥相等运算符(===)进行判断,这会导致对NaN的误判
8、数组的空位
数组的空位值,数组的某一个位置没有任何值。空位不是undefined,一个位置的值等于undefined,依然是有值的。空位时没有任何值,in运算符可以说明这一点
函数的扩展
参数已经声明,所以不能再用let或者const再次声明
函数的length属性
指定了默认值以后,函数的length属性,将返回没有指定默认值得参数的个数,也就是说,指定了默认值参数,length属性将失真
如果设置了默认值得参数不是尾参数,那么length属性也不再计入后面的参数了
作用域
一旦设置了参数的默认值,参数会形成一个单独的作用域,等到初始化结束,这个作用域就会消失(如果不设置参数默认值,是不会出现的)
如果参数的默认值是一个函数,该函数的作用域也遵守这个规则
注意下区别
reset函数(形式为“...”变量名)
它的作用是获取函数的多余参数,这样就不需要使用arguments对象了,rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中
rest参数中的变量代表一个数组(...变量名)好奇怪的写法
注意reset参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
函数lenght属性,不包括rest参数
扩展运算符(spread...)
它的作用好比reset参数的逆运算,将一个数组转为用逗号分隔的参数序列
这里小结下,reset是多余的参数中放入到数组中,而扩展运算符是将数组转为用逗号分隔的参数序列
替代数组的apply方法
由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了
看看这个例子,之前不明白ES5的写法为什么一定要加上apply的方法,现在明白了,是因为push方法的参数不能是数组,所以只好通过apply方法变通使用push方法
扩展运算符的应用
1)合并数组
2)与解构赋值结合
扩展运算符用于数组赋值,只能放在参数的最后一位
3)函数的返回值
扩展运算符可以返回多个值
4)字符串
扩展运算符还可以经字符串转为真正的数组
5)实现了遍历接口的对象
var nodelist = document.querySelectorAll('div');
var array = [...nodeList];
但是对于没有不熟遍历接口类似数组的对象,可以使用Array.from方法獎arrayLike转为整整的数组
6)Map和Set结构,Generator函数
反正只要有遍历接口,都可以使用扩展运算符
name属性,返回该函数的函数名
注意:1)如果将一个匿名函数赋给一个便令,ES5的name属性,返回空字符串,而ES6的name属性会返回实际的函数名
2)如果将一个具名函数赋值给一个变量,则ES5和ES6的那么属性都返回这个具名函数原本的名字
3)Function构造函数返回的函数实例,那么属性的值为anonymous,bind返回的函数,name 属性值会加上bound前缀
箭头函数
之前我是不太明白这种写法的,现在一看就明白了,=>这个后面是返回值的意思
如果返回值是一个对象的话,那么使用括号

再看看几个例子
简化回调函数
注意点:函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象
setTimeout函数的this指向window,所以结果是21;而setTimeout的参数是一个箭头函数,this指向函数定义生效时所在的对象(本例是{id:42}),所以结果是42
上面的Timer函数内部设置了两个定时器,分别使用了箭头函数和普通函数,前者的this绑定定义所在的作用域(timer函数),后者的this指向运行时所在的作用域(即全局对象)
this指向的固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数更笨没有自己的this,导致内部的this就是外层代码块的this.正式因为他没有this,所以也就不能用作构造函数
除了this,arguments\super\new.target在箭头函数之中也是不存在的,所以当然也不用call()、apply()、bind()这些方法去改变this的指向
绑定this(Es7提出了函数绑定运算符,但是Babel转码器已经支持)
函数绑定运算符并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数,该运算符会自动将左边的对象,作为上下文环境,绑定到右边的函数上面
尾调用:是函数式变成的一个重要改变,就是只某个函数的最后一步是调用另一个函数
只有第四种属于尾部调用,第三种和第五种是一样的意思