ES6语法——数组Array扩展
一、 扩展运算符
扩展运算符(spread)是三个点(...)。它好比 rest 参数(将多余的参数转换成数组)的逆运算,将一个数组转为用逗号分隔的参数序列。
扩展运算符的使用场景:
(一)扩展运算符与正常的函数参数结合使用
(二)扩展运算符后面还可以放置表达式
(三)如果扩展运算符后面是一个空数组,则不产生任何效果
(四)替代数组的 apply 方法
(五)简化求出一个数组最大值与最小值
(六)复制数组
(七)合并数组
(八)与解构赋值结合
(九)将字符串转换成数组(扩展运算符还可以将字符串转为真正的数组)
(十)实现了 Iterator 接口的对象
(十一)Map 和 Set 结构,Generator 函数
个人理解,这个扩展运算符 ... 有以下几种使用情况
(1)在函数参数括号里面就是做rest参数,是将多余的实参转换成数组,且rest参数只能在最后一位
(2)...紧跟一个显示声明了的变量,说明这是解构赋值,这个变量返回一个数组,这个数组接收多余的参数
(3)... 紧跟一个数组,扩展运算符会将数组转换成有序的参数列表
(4)... 紧跟一个字符串,扩展运算符会将这个字符串转换成数组
(5)... 紧跟一个具有Iterator接口的对象,扩展运算符会将这个对象转换成数组
二、 Array.from()
Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
值得提醒的是,扩展运算符(...)也可以将某些数据结构转为数组。其实扩展运算符(...)和Array.from()这两种方式的原理都是利用对象内部的iterator遍历接口去实现的。
下面列举Array.from()方法使用的注意事项:
(一) Array.from()方法可以将具有length属性的对象转换成数组
(二)Array.from()还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
(三)Array.from()方法接收第三个参数:如果Array.from接收的第二个类似map函数的参数中使用到了this关键字的话, Array.from()还可以接收第三个参数来绑定this值
(四)Array.from()的另一个应用是,将字符串转为数组,然后返回字符串的长度。因为它能正确处理各种 Unicode 字符,可以避免 JavaScript 将大于 \uFFFF的 Unicode 字符,算作两个字符的 bug。
三、 Array.of()
Array.of方法用于将一组值,转换为数组
Array.of方法用于弥补new Array() 和Array()方法生成数组的不足,Array方法没有参数、一个参数、三个参数时,返回结果都不一样。只有当参数个数不少于 2 个时,new Array()和Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。
Array.of总是返回参数值组成的数组。如果没有参数,就返回一个空数组
四、 数组实例的 copyWithin()
数组实例的copyWithin()方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法, 会修改当前数组。
target(必需):从该位置开始替换数据。
start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示倒数。
end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。如果不设置end就默认到数组的末尾端。
上面代码表示将从 4 号(包括4号位本身)位直到8号位之前(不包括8号位本身)的,复制到从 2 号位(包括其本身)开始的位置,结果覆盖了原来的3,4,5,3。
这三个参数都应该是数值,如果不是,会自动转为数值。
五、数组实例的 find() 和 findIndex()
(一)find(callback(value,index,arr))方法
官方版解释:数组实例的find()方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为 true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。
个人理解:find(callback),找到第一个符合callback函数的成员,find(callback)方法返回第一个使callback返回值为true的数组成员,否则返回undefined。
通俗的讲,find方法就是返回第一个符合回调函数条件的那个数组成员
(二)findIndex(callback(value,index,arr))
数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。
值得注意的是:
(1)find()和findInde()这两个方法接收的回调函数可以接收三个参数: 依次为当前的值value、当前的位置index和原数组Array。
(2)find()和findInde()这两个方法还除了接收第一个回调callback函数,还可以接收第二个参数来绑定这个回调函数callback的this对象。
(3)find()和findInde()这两个方法都可以发现NaN,弥补了数组的indexOf方法的不足。
这里使用到对象新增的方法Object.is()方法,这个方法就是判断两个值是不是相等,特性是:NaN===NaN为true +0===-0为false
六、 数组实例的 fill()
fill()方法使用给定值(这个值是第一个参数的位置),填充一个数组。
上面代码表明,fill方法用于空数组的初始化非常方便。数组中已有的元素,会被全部抹去。
fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置(包含,从这个位置开始)和结束位置(不包含这个位置,在这个位置之前结束)。
上面代码显示:fill()从 1 号位开始,向原数组填充 7,到 3号位之前(不包括3号位)结束。
七、 数组实例的 entries(),keys() 和 values()
ES6 提供三个新的方法——entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象,可以用 for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。
如果不使用for...of循环,可以手动调用遍历器Iterator对象的next方法,进行遍历。
entries()方法返回的是包含键值对的遍历器Iterator对象,这个遍历器的next方法返回的是一个对象(包含value属性和done属性),这个对象的value就是数组的每一项的键值对(详见Iterator遍历器)
八、数组实例的 includes()
Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似
需要注意的是:
(一)includes()方法,传入的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但 数组长度为3),则会重置为从0开始。
(二)关于NaN的问题:
在ES6之前,检测一个数组中是否含有某个元素的话,采用indexOf()方法,含有就返回找到这个元素的第一个位置,没有找到就返回-1(使用起来就得判断返回值是否不等于-1)。最主要的是indexOf()方法的内部采用严格的(===)运算符进行判断,这会导致对NaN进行误判(NaN==NaN=>false JavaScript比较特殊的自己本身不等于自己的)
ES6新增的includes()方法可以正确的判断出数组中是否含有NaN这个元素
九、数组的空位
含义:数组的空位指,数组的某一个位置没有任何值。
强调的是空位是没有任何值的,空位不是undefined,也不是null,也不是0
ES5以及ES6对空位的处理:
(一)ES5 对空位的处理,已经很不一致了,大多数情况下会忽略空位。
1. forEach(), filter(), every() 和some()都会跳过空位。
2. map()会跳过空位,但会保留这个值
3. join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。
(二)ES6对空位的处理:
1. ES6 则是明确将空位转为undefined
2. ES6不同方法之间对于空位的处理还是有些许的差异的,例如:
(1) Array.from方法会将数组的空位,转为undefined,也就是说,Array.from()这个方法不会忽略空位。
(2) 扩展运算符(...)也会将空位转为undefined。
(3) copyWithin()会连空位一起拷贝。
(4) fill()会将空位视为正常的数组位置。
(5) for...of循环也会遍历空位。
(6) entries()、keys()、values()、find()和findIndex()会将空位处理成undefined。
由于处理的标准各有差异,建议避免出现空位