ES6学习笔记(七)数组的扩展

扩展运算符


扩展运算符的使用

跟rest参数刚好相反,rest参数是将多个逗号分隔的参数转为一个数组,而扩展运算符是将数组转为逗号分隔的参数

扩展运算符后面可放表达式,表达式的结果要是一个带有Iterator接口的数据结构,如果后面是一个空数组,则返回空,而如果放在括号内,则会被认为是函数调用

扩展运算符内部调用的是数据结构的 Iterator 接口只要带有Iterator接口,就可以使用扩展运算符转为数组,没有Iterator接口的对象添加Iterator接口后就可以使用扩展运算符转为数组

[...[1,2,3]]//[1,2,3]
[...(Math.random()*10>5?['big']:['small'])]//生成随机数大于5得到["big"],小于5得到["small"]
[...[]]//[]

扩展运算符的应用

1.代替apply函数

在ES5中,如果要找出一个数组的最大值,我们可以通过使用Math.max.apply(null,arr)来实现,而在ES6中,可以通过扩展运算符直接将数组作为参数传进去。

let arr=[1,2,3];
Math.max.apply(null,arr);//3      ES5的写法
Math.max(...arr);//3       ES6的写法

2.扩展Set结构和Map结构

let s=new Set([1,2,3]);
[...s];//[1,2,3]
let m=new Map([[1,2],[2,3]]);
[...m];//[[1,2],[2,3]]

3.复制数组

用赋值符号“=”来复制数组,实际上是复制值所在的地址,若修改了其中一个的值,另一个也会发生改变,所以在ES5中,要通过concat来复制数组,而在ES6中,通过扩展运算符就可以直接复制数组了

var arr1=[1,2,3];
var arr2=arr1;
arr2[0]=2;
arr1;//[2,2,3];


arr2=arr1.concat();
arr2[0]=3;
arr1;//[2,2,3];
arr2;//[3,2,3];


arr2=[...arr1];
arr2[0]=4;
arr1;//[2,2,3]
arr2;//[4,2,3]

4.合并数组

使用扩展运算符可以很方便地合并数组,将多个带扩展运算符的数组放入[]内赋值给另一个数组即合并了数组,要注意的是,这里用到的是浅拷贝,如果数组成员是对象的话,原数组对象中的属性发生改变,合并数组中的属性也会发生改变。

var arr1=[1,2,3];
var arr2=[4,5,6];
var arr3=[...arr1,...arr2];//[1,2,3,4,5,6]


var person1=[{name:"john",age:18}];
var person2=[{name:"Bob",age:20}];
var person3=[...person1,...person2];//[{name:"john",age:18},{name:"Bob",age:20}]
person1[0].name="jack";
person3;//[{name:"jack",age:18},{name:"Bob",age:20}]

5.将数组成员作为函数参数

let arr=[1,2,3,4]
function fn(){
    for(let i of arguments){
        console.log(i);
    }
}//1   2   3   4
fn(...arr)

Array.from


Array.from用于将类似数组的对象和可遍历的对象转化为数组

相对于只能转化有Iterator接口的数据结构的扩展运算符,Array.from可转化的范围更大,任何有length属性的对象都可以转为数组(如果传入的是一个数组的话,则生成一个相同的新数组)

Array.from([1,2,3]);//[1,2,3]
Array.from(new Set([1,2,3]);//[1,2,3]
Array.from({length:3});//[undefined,undefined,undefined]

没有部署Array.from的浏览器可以用Array.prototype.slice代替

const toArray = (() =>
  Array.from ? Array.from : obj => [].slice.call(obj)
)();

传入的第二个参数其实等同于只传入第一个参数转为数组后调用数组的map方法,把第二个参数作为调用的map方法的参数,对生成的数组中的每个值执行第二个参数的操作后返回操作后的数组(如果map中使用了this,可以使用第三个参数来指定this的指向)

Array.from([1,2,3,4],val=>val=val*2);//[2,4,6,8]


var person={name:"john",age:18}
function fn(val){
    return val>this.age;
}
Array.from([10,20,30,40],fn,person);//[false,true,true,true];

这里要注意的是如果要使用this,第二个参数就不要使用箭头函数来表示,因为箭头函数没有this,如果在这里使用了箭头函数,函数体里的this就会指向外部的this。

Array.of


Array.of用于将传入的参数作为数组成员生成一个数组,这个方法用于解决ES5中用new Array生成数组时传入不同的参数会有不同的处理机制的问题,如果使用new Array生成数组,传入的参数为一个时生成长度为该参数的空位数组,而其他情况则将传入参数作为数组成员生成一个数组。而Array.of不管传入几个参数,都和new Array传入非1参数的情况相同。

new Array();//[]
new Array(3);//[,,]
new Array(3,4,5);//[3,4,5]


Array.of();//[]
Array.of(3);//[3]
Array.of(3,4,5);//[3,4,5]

在不支持Array.of的场合,可以声明一个函数,将传入的arguments用[].slice.call(arguments)处理后返回,与使用Array.of结果相同

function ArrayOf(){
  return [].slice.call(arguments);
}

copyWithin


copyWithin将数组中的一部分覆盖另一部分,该方法会修改原数组,返回新的数组

copyWithin(target,start=0,end=length-1)

target:覆盖的起始点,必需的

start:用于覆盖的部分的起点,可选的,默认值为0

end:用于覆盖部分的终点,可选的,默认值为length-1

三个参数的数值必须为数值,如果不是数值,会被强行转为数值,如果是浮点数,会向下取整(后面有用到start和end的参数的地方也一样

[1,2,3,4].copyWithin(2);//[1,2,1,2]
[1,2,3,4].copyWithin(0,1);//[2,3,4,4]
[1,2,3,4].copyWithin(0,1,3);//[2,3,3,4]
[1,2,3,4].copyWithin(0,-1);//[4,2,3,4]
[1,2,3,4].copyWithin(0,-3,-1);//[2,3,3,4]

find和findIndex


find用于找出数组中第一个符合条件的数组成员,如果没找到则返回undefined。

find的回调函数可以接受三个参数,依次为当前位置的值,当前位置的下标,原数组

[1,2,3].find(function(value,index,arr){

return value>1;

}//2

find可以接收第二个参数,用于指定回调函数中的this

function f(value){
    return value>this.age;
}
var person={name:"jack",age:20};
[13,24,44].find(f,person);//24

find可以利用isNaN()或者Object.is()来找到NaN,弥补了indexof的不足

[NaN].find(value=>isNaN(value))//NaN
[NaN].find(value=>Object.is(NaN,value));//NaN

findIndex用法和find一样,但找到的时候返回的是找到的位置的下标,找不到的时候返回-1。

fill


fill用于用一个值填充整个数组或者数组的部分位置

fill(value,start=0,end=length-1)

value:用于填充数组的值

start:开始填充的位置,默认为0

end:结束填充的位置,默认为length-1

该方法的填充为浅拷贝,若用于填充的是对象,那么修改其中一个对象的属性,其他都会跟着改变

['a', 'b', 'c'].fill(7)
// [7, 7, 7]

new Array(3).fill(7)
// [7, 7, 7]

let arr = new Array(3).fill({name: "Mike"});
arr[0].name = "Ben";
arr
// [{name: "Ben"}, {name: "Ben"}, {name: "Ben"}]

遍历方法keys,values,entries


keys()用于对键名的遍历,values用于对键值的遍历,entries是用于对键值对的遍历

for (let index of ['a', 'b'].keys()) {
  console.log(index);
}
// 0
// 1

for (let elem of ['a', 'b'].values()) {
  console.log(elem);
}
// 'a'
// 'b'

for (let [index, elem] of ['a', 'b'].entries()) {
  console.log(index, elem);
}
// 0 "a"
// 1 "b"

Includes


includes用于查找当前数值有没有和传入的参数相等的值,有则返回true,没有则返回false

includes(value,start)

value:要查找的值

start:开始查找的位置,为负数时表示倒数的位置。如果是正数且大于数组长度,就只查找最后一个数,如果是负数且绝对值大于数组长度,则从0开始查起,默认值为0

includes同样可以找到NaN

[1,2,3,4].includes(2);//true

[1,2,3,4].includes(2,0);//true

[1,2,3,4].includes(5,0);//false

[1,2,3,4].includes(4,10);//true

[1,2,3,4].includes(1,-10);//true

[NaN].includes(NaN);//true

flat和flatMap


flat用于将数组降低维数,传入的参数为降低的维数,默认为1,如果要保证降到一维,可以传入Infinity,如果原数组有空位,flat会跳过空位

[1,2,3,[4,5]].flat();//[1,2,3,4,5]

[1,2,3,[[4],5]].flat(2);//[1,2,3,4,5]

[1, [2, [3]]].flat(Infinity)// [1, 2, 3]

flatMap对每个数组成员执行一个类似map函数,执行后再对该数组执行flat(),但是只能展开一层数组,其第二个参数可用于绑定第一个参数中的函数的this。

对数组空位的处理


ES5对数组空位的处理

forEach(), filter(), reduce(), every() 和some()都会跳过空位。

map()会跳过空位,但会保留这个值

join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。

// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1

// filter方法
['a',,'b'].filter(x => true) // ['a','b']

// every方法
[,'a'].every(x => x==='a') // true

// reduce方法
[1,,2].reduce((x,y) => x+y) // 3

// some方法
[,'a'].some(x => x !== 'a') // false

// map方法
[,'a'].map(x => 1) // [,1]

// join方法
[,'a',undefined,null].join('#') // "#a##"

// toString方法
[,'a',undefined,null].toString() // ",a,,"

ES6在处理空位时将其视为undefined,即不会忽略空位,在用copyWithin拷贝时会拷贝空位

将空位视为undefined的方法:Array.from,扩展运算符,entries(),keys(),values(),find()和findIndex()

Array.from(['a',,'b'])
// [ "a", undefined, "b" ]

[...['a',,'b']]
// [ "a", undefined, "b" ]

[,'a','b',,].copyWithin(2,0) // [,"a",,"a"]

new Array(3).fill('a') // ["a","a","a"]

let arr = [, ,];
for (let i of arr) {
  console.log(1);
}
// 1
// 1

// entries()
[...[,'a'].entries()] // [[0,undefined], [1,"a"]]

// keys()
[...[,'a'].keys()] // [0,1]

// values()
[...[,'a'].values()] // [undefined,"a"]

// find()
[,'a'].find(x => true) // undefined

// findIndex()
[,'a'].findIndex(x => true) // 0

参考自阮一峰的《ECMAScript6入门》

猜你喜欢

转载自blog.csdn.net/zemprogram/article/details/86440311
今日推荐