第八章 数组的扩展
8.1扩展运算符
8.1.1含义
扩展运算符是三个点(...),它如同rest参数的逆运算,讲一个数组转化为用逗号分隔的参数序列。
console.log(...[1,2,3])
//1,2,3
该运算符主要用于函数调用。
扩展运算符后面还可以放置表达式,
如果扩展运算符后面上第一个空数组,则不产生任何效果。
8.1.2
扩展运算符可以展开数组,所以就不需要使用apply方法将数组转化为函数的参数。
es5的写法。
function f(x,y,z){
}
var arge=[0,1,2,3]
f.apply(null,arge)
Es6写法:
function f(x,y,z){
...
}
var arge =[0,1,2,3];
f(...arge);
push方法的参数不可以是数组,只好通过apply方法变通使用push方法,,可以直接将数组传入push方法。
8.1.3扩展运算符的运用
合并数组
es5
[1,2].concat(more);
es6
[1,2,...more]
es5 数组合并
var a=[1,2]
var b=[3,4]
a.concat(b);
es6
[...a,...b]
与解构赋值结合
扩展运算符可以与解构赋值结合起来,用于生成数组。
如果将扩展运算符用于数组赋值,则只能将其放在参数的最后一位,否则会报错。
函数的返回值
js的函数只哼返回一个值,如果需要多个返回值,只能返回数组和 对象,扩展运算符提供了解决这中的一种变通方法。
扩展运算符还可以将字符串转为真正的数组。
[...'hello'];
//['h','e','l','l','o']
8.2Array.from()
此方法可以将两类对象转为真正的数组,类似数组的对象和可遍历的对象,包括es6新增的set和map
下面是一个类数组
let a ={
'0':'a',
'1':'b',
'2':'c',
length:3
}
es5写法:
var arr.slice.call(a);//['a','b','c'];
es6写法:
var arr=Array.from(a);//['a','b','c']
常见的类似数组的对象时DOM操作返回的NodeLIst集合,以及函数内部的arguments对象,Array.from
都可以将他们转为真正的数组、。
只有转化为正真的数组,才能使用forEach方法。
如果参数是一个真正的数组,Array.from()返回的是一个一模一样的新数组。
值得提醒的是。扩展运算符(...)也可以将某些数据结构转化为数组。
扩展运算符背后调用的是遍历器接口(symbol.iterator),如果一个对象没有部署改接口,Array.from方法就无法支持列斯数组的对象,
对于没有支持该方法的浏览器,可以使用Array.protortype.slice代替。、
Array.from 还可以传入第二个参数 ,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
如果map函数里面用到了this 这个关键字,还可以传入Array.from第三个参数,用来绑定this。
Array.from()还可以将各种值转为真正的数组,,并且提供map的功能,这意味着,只要有一个原始数据结构,就可以先对他的值进行处理,然后转成规范的数组结构。
Array.from ()的另一个应用是,将字符串转为数组,返回字符串的长度,因为它能处理各种Unicode字符,可以避免js将大于\uFFFF的Unicode子字符作为2个字符的bug。
8.3Array.of()
用于将一组值转换为数组。
Array.of(1,2,3)//[1.2.3]
Array.of(1)//[1]
Array.of(3).length//1
这个方法主要用来弥补数组构造函数Array()的不足之处,因为参数的不同会导致Array()的行为有差异。
Array()//[]
Array(3)//[ , , ,]
Array(1,2,3)//[1,2,3]
只有当参数不少于2个的时候,Array()才会返回由数组组成的新数组,参数只有1个的时候,实际上指的是数组的长度。
Array.of基本上可以取代Array()和new Array(),并且不存在由于参数不同而导致的重载,行为非常统一。
Array.of总是返回的是数值组成的数组,如果没有参数,就返回一个空的数组。
Array.of的方法可以用下面的方法实现
function ArrayOf(){
return [].slice .call(argumnets)
}
8.4数组实例的copyWithin()
会在当前数组内将指定的位置的成员复制到其他的位置,(会覆盖原有成员),然后返回当前的数组,就是说,这个方法会修改当前数组。
Array.prototype.copyWithin(target,start=0,end=this.length);
接受3个 参数
target:必选。从该位置开始替换数据
start:可选:从该位置读取数据,默认是0,如果为负数,表示倒数。
end:可选:到该位置前停止读取书库,默认等于数组长度,如果为负值,表示倒数。这3 个参数都应该是数值,如果不是的话,会自动转为数值。
[1,2,3,4,5].copyWithin(0,3)//[4,5,3,4,5]
上面的意思是将从3号位置直到数组结束的成员(4,5)复制到从0号位置开始的位置,结果覆盖了原来的1和2.
8.5数组实例的find()和finindex()
find方法适用于找出处第一个复合条件的数组成员,他的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找到各一个返回值为true的成员,然后返回该成员,如果没有复合条件的成员,返回的则是undefined。
find回调函数可以接受3个参数,依次为当前的值,当前的位置和原数组。
数组findindex方法的与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1.
这两个方法都可以接受第二个参数,用来绑定回调函数的this对象。另外,这两方法艘可以发现NaN,弥补了数组的indexOf的不足之处。
8.6数组实例的fill()
此方法用于空数组的初始化时非常好用。数组中的所有元素都会被前部抹去。
用于给定值填充一个数组。
['a','b','c'].fill(7)//[7,7,7]
fill方法还可以接受第二个参数和第三个参数,用于指定填充的起始位置和结束位置。 结束位置不包括自己
8.7数组实例的entries()/keys()和values();
es6新增的3个方法,用于遍历数组,他们都返回一个遍历器的对象,for...of循环,keys()是对键命的遍历,values()是对键值的遍历,entries()是对键值对的遍历。
如果不使用for...of循环,可以使用遍历器对象的next方法进行遍历。
8.8数组实例的includes()
Array.prototype.includes返回的是一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似,es6将其引入进来,
该方法的第二个参数表示搜索的起始位置,默认是0,如果第二个参数为负数,表示倒数的位置,如果他大于数组长度,则会重置从0开始。
没有此方法之前,我们用indexof方法检查是否包含某个值,
indexOf的缺点是不够语义,其含义找到参数某个值得时候的第一个位置,要比较是否等于-1,二是内部使用严格相等进行判断,会导致对NaN的误判、
[NaN].indexOf(NaN)//-1.