今天看啥  ›  专栏  ›  legendaryedu

重学ES6 数组扩展(2)

legendaryedu  · 掘金  ·  · 2019-05-10 10:33
阅读 16

重学ES6 数组扩展(2)

方法

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']
//es6
let 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');
// map
let 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] //true
0 in [, , ,] // false复制代码



原文地址:访问原文地址
快照地址: 访问文章快照