方法
Array.from()
Array.from(),将两类对象转成真正的数组:类似数组的对象
和可遍历的对象
(包括Map和Set结构)
let arrayLike = { '0':'a', '1':'b', '2':'c', length:3}//es5写法var arr1 = [].slice.call(arrayLike); //['a','b','c']//es6let arr2 = Array.from(arrayLike); //['a','b','c']复制代码
常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments对象,都可以将他们转化成为真正的数组。
只要部署了Iterator接口的数据结构,Array.from都能将其转化为数组。
扩展运算符 ... 也可以将某些数据结构转化为数组。
扩展元算符背后调用的是遍历接口(symbol.iterator),如果一个对象没有部署该接口,就无法转换。Array.from方法还支持类似数组的对象。类数组对象,本质只有一点,必须有 length 属性,因此,任何有length属性的对象,都可以通过Array.from方法转为数组,但是扩展运算符无法转换。
Array.from({ length:3 });// [ undefined, undefined, undefined]复制代码
兼容写法
const toArray = (()=>{ Array.from ? Array.from : obj => [].slice.call( obj )})();复制代码
Array.from还可以接受第二个参数,作用类似于数组的map方法。用于对每个元素进行处理,将处理后的值放到返回的数组里。
Array.from(arrayLike, x => x * x);//等同Array.from(arrayLike).map(x => x * x)复制代码
取DOM节点文本内容
let spans = document.querySelectorAll('span.name');// maplet names1 = Array.prototype.map.call(spans, s => s.textContent);//Array.from()let names2 = Array.from(spans, s => s.textContent);复制代码
将数组中值为 false 的转化为0
Array.from([1,,2,,3], (n) => n|| 0);//[1,0,2,0,3]复制代码
将字符串转化为数组
function countSymbols(string){ return Array.from(string).length;}countSymbols("aaa") //3复制代码
Array.of()
用于将一组值转化为数组
Array.of(3,11,8); //[3,11,8]Array.of(4); //[4]复制代码
这个方法是为了弥补数组构建函数Array()的不足。因为参数个数不同,导致Array行为有差异。
Array() //[]Array(3)//[,,,]Array(3,11,8) //[3,11,8]复制代码
Array.of()基本可以代替Array 或者 new Array,并不存在因为参数不同导致的函数重载。
Array.of() //[]Array.of(undefined) //[undefined]Array.of(1) //[1]Array.of(1,2) //[1,2]复制代码
Array.of 总是返回参数值组成的数组。如果没有参数,返回一个空数组。
Array.of 模拟实现
function ArrayOf(){ return [].slice.call(arguments)}复制代码
数组实例的 copyWithin()
数组实例copyWithin方法,会在当前数组内部将指定位置成员复制到其他位置(会覆盖原有成员),然后返回当前数组,方法会修改当前数组。
Array.prototype.coptWithin(target, start=0, end=this.length)
target(必选):从该位置开始替换数据
start(可选):从该位置开始读取数据,默认为0,如果为负值,表示倒数。
end(可选):到该位置停止读取数据,默认等于数组长度。如果为负值,表示倒数。
这3个参数都应该是数值,如果不是,会自动转成数值。
find()和 findIndex()
数组实例的find,用于找到第一个符合条件的数组成员。参数是一个回调函数,所有数组成员依次执行该回调函数,直到找到第一个返回值为true的成员,然后返回该成员,如果没有,则返回 undefined。
[1,4,-5,3].find((n) => n < 0)// -5[1,5,10,15].find(function(value,index,arr){ // 当前值,当前值位置,原数组 return value > 9;})//10复制代码
数组实例的findIndex用法与find非常相似,返回第一个符合条件的成员位置,如果都不符合,返回 -1
[1,5,10,15].findIndex(function(value,index,arr){ return value > 9;})//2复制代码
fill()
['a','b','c'].fill(7)// [7,7,7]new Array(3).fill(7)// [7,7,7]复制代码
fill还可以接受第二个,第三个参数,指定起始位置和结束位置
['a','b','c'].fill(7,1,2);// ['a',7,'b']复制代码
entires()、 keys()、 values()
以上三个方法,都返回一个遍历器对象,可用for...of循环遍历,唯一的区别,keys 是对键名的遍历,values 是对键值的遍历,entires 是对键值对的遍历。
for(let index of ['a','b'].keys()){ console.log(index)}// 0// 1复制代码
for(let index of ['a','b'].values()){ console.log(index)}// 'a'// 'b'复制代码
for(let index of ['a','b'].entires()){ console.log(index,elem)}// 0 'a'// 1 'b'复制代码
还可以手动调用遍历器对象的 next 方法进行遍历
let letter = ['a','b','c'];let entires = letter.entires();console.log(entires.next().value); // [0,'a']console.log(entires.next().value); // [1,'b']console.log(entires.next().value); // [2,'c']复制代码
includes()
返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes类似。
[1,2,3].includes(2) //true[1,2,3].includes(4) //false[1,2,NaN].includes(NaN) //true复制代码
该方法的第二个参数表示搜索的起始位置,默认为0.如果第二个参数为负数,表示倒数的位置,如果大于数组长度,将重置为0.
[1,2,3].includes(3,3); //false[1,2,3].includes(3,-1); //true复制代码
indexOf方法有两个缺点
- 不够语义化,含义是:找到参数值第一个出现的位置,所以,比较是否不等于 -1 ,不够直观。
- 内部使用 === 进行判断,会导致误判。
[NaN].indexOf(NaN) //-1[NaN].includes(NaN) // true复制代码
下面代码用来检查当前环境是否支持该方法,如果不支持,采用一个简易的代替版本。
const contains = (()=> Array.prototype.includes ?(arr,value) => arr.includes(value) :(arr,value) => arr.some(el => el === value))();contains(['foo','bar'],'baz'); // false复制代码
Map结构的has用来查找键名。
Set结构has用来查找值。
数组的空位
Array(3) //[, , ,]复制代码
注意,空位不是 undefined,一个位置的值等于 undefeated,依然是有值的。空位是没有任何值的,in 运算符可以说明这一点。
0 in [undefined,undefined,undefined] //true0 in [, , ,] // false复制代码