一、扩展运算符
1、格式
...数组名
console.log([1,2,3]);//Array(3) [ 1, 2, 3 ]
console.log(...[1,2,3]);//1 2 3
2、作用(主要用于函数调用)
把数组转化为用逗号“,”分隔的参数序列(与rest参数的区别于,rest参数是写在函数的圆括号的参数,是把用逗号分隔的参数序列转化为数组;而且替代了apply()【apply()把数组转为函数的参数序列】)。
以下是rest参数和扩展运算符在函数的使用案例: 通过rest参数把传入函数的未知个数的参数序列转化为数组,然后通过扩展运算符把数组转为以逗号分割的参数序列加入到arr里。
function f(...value){
let arr = [];
//value [1,2,3,4]
arr.push(...value)//1,2,3,4
console.log(arr);//Array(4) [ 1, 2, 3, 4 ]
}
f(1,2,3,4)
以下使用apply()把数组转为函数的参数案例:
function f(x,y,z){
console.log(x,y,z);//1 2 3
}
let arr=[1,2,3]
f.apply(null,arr)
3、应用
(1)、数组的最大值、最小值:
//使用扩展运算符
let arr=[1,2,3,4]
console.log(Math.max(...arr));//4
console.log(Math.min(...arr));//1
//使用apply()
let arr=[1,2,3,4]
console.log(Math.max.apply(null,arr));//4
console.log(Math.min.apply(null,arr));//1
(2)、数组尾部添加多个元素
//使用扩展运算符
let arr1=[1,2,3,4]
let arr2=[5,6,7]
arr1.push(...arr2)
console.log(arr1);//Array(7) [ 1, 2, 3, 4, 5, 6, 7 ]
//使用apply()
let arr1=[1,2,3,4]
let arr2=[5,6,7]
Array.prototype.push.apply(arr1,arr2)
console.log(arr1);//Array(7) [ 1, 2, 3, 4, 5, 6, 7 ]
(3)、复制数组(常用)
由于数组是复合数据类型,直接赋值指向的是底层数据结构的指针,而不是克隆一个全新的数组。如下案例里arr1或arr2任意一个发生改变,另一个也会发生改变。
let arr1=[1,2,3]
let arr2=arr1
arr2[0]="1111"
console.log(arr1);//Array(3) [ "1111", 2, 3 ]
console.log(arr2);//Array(3) [ "1111", 2, 3 ]
以下使用扩展运算符解决数组赋值问题:
let arr1=[1,2,3]
let arr2=[...arr1]
arr2[0]="1111"
console.log(arr1);//Array(3) [ 1, 2, 3 ]
console.log(arr2);//Array(3) [ "1111", 2, 3 ]
以下使用arr.concat()解决数组赋值问题:
let arr1=[1,2,3]
let arr2=arr1.concat()
arr2[0]="1111"
console.log(arr1);//Array(3)[ 1, 2, 3 ]
console.log(arr2);//Array(3) [ "1111", 2, 3 ]
(4)、合并数组(浅拷贝:如果修改了引用指向的值,会同步反映到新数组)
//使用arr=arr1.concat(arr2,arr3)合并新数组
let arr1=[1,2,3]
let arr2=[4,5,6]
let arr3=[7,8,9]
let arr4=arr1.concat(arr2,arr3);
console.log(arr4);//Array(9) [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
// 使用扩展运算符合并一个新数组
let arr1=[1,2,3]
let arr2=[4,5,6]
let arr3=[7,8,9]
let arr4=[...arr1,...arr2,...arr3]
console.log(arr4);//Array(9) [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
(5)、扩展运算符(只能放在最后一位)与解构赋值产生新数组
let [first,...arr]=[1,2,3]
console.log(first);//1
console.log(arr);//Array [ 2, 3 ]
(6)、把字符串转为数组
let s = "hello"
console.log([...s]);//Array(5) [ "h", "e", "l", "l", "o" ]
(7)、与Map结合使用获取数组里指定下标值
let map = new Map([
[1,11],
[2,22],
[3,33]
])
console.log([...map.keys()]);//Array(3) [ 1, 2, 3 ]
console.log([...map.values()]);//Array(3) [ 11, 22, 33 ]
console.log([...map]);//Array(3) [[1,11],[2,22],[3,33]]
二、Array.from()
1、把对象里值、数组、Set结构等具有Iterator接口,转为真正数组。
// 注意key值为数组,要加上length属性
let obj={
0:1,
1:"yt",
2:"男",
length: 3
}
console.log(Array.from(obj));//Array(3) [ 1, "yt", "男" ]
以上写法等价于[].slice.call(obj)
let s="hello"
console.log(Array.from(s));//Array(5) [ "h", "e", "l", "l", "o" ]
let set =new Set([1,2,3])
console.log(set);//Set(3) [ 1, 2, 3 ]
console.log(Array.from(set));//Array(3) [ 1, 2, 3 ]
2、对数组中的元素进行处理
// 把不存在的元素的位置添加0
let arr = [1,,2,2,3,,4]
console.log(Array.from(arr,(n)=>n||0));
//Array(7) [ 1, 0, 2, 2, 3, 0, 4 ]
// 返回各种数组类型
function typeFunction(){
return Array.from(arguments,(n)=>typeof n)
}
console.log(typeFunction(1,"1",[1,2,3]));
//Array(3) [ "number", "string", "object" ]
三、Array.of():把一组值转化为数组
console.log(Array.of());//Array []
console.log(Array.of(1,2,3));//Array(3) [ 1, 2, 3 ]
console.log(Array.of(3));//Array [ 3 ]
四、copyWithin(指定某位置开始替换【可以为负数】,开始读取位置,停止读取位置):把数组指定位置的元素替换成某元素(这些元素都是数组内部元素)
let arr = [1,2,3,4,5]
arr.copyWithin(0,2,4)
//读取下标为2到4【不包括4】的元素是(3,4),从下标为0开始覆盖元素(1,2)
console.log(arr);//Array(5) [ 3, 4, 3, 4, 5 ]
let arr = [1,2,3,4,5]
arr.copyWithin(0,-3,-1)//-1表示元素5,-3表示元3
console.log(arr);//Array(5) [ 3, 4, 3, 4, 5 ]
五、数组寻找符合条件的成员
1、find():只返回第一个符合条件的元素。
//存在
console.log([1,2,3,4].find(n=>n>2));//3
//不存在
console.log([1,2,3,4].find(n=>n<1));//undefined
// find()方法回调函数可以接受三个参数(当前值、当前位置,原数组)
console.log([1, 2, 3,4,5].find(function (value, index, arr) {
return value>4
}));//5
2、findIndex():只返回第一符合条件的元素下标。
console.log(["x","y","z"].findIndex( n=>n=="z"));//2
console.log(["x","y","z"].findIndex( n=>n=="c"));//-1
console.log(["x","y","z"].findIndex(function(value,index,arr){
return value=="z"
}))//2
3、findLas()t和findLastIndex():从最后一个元素寻找符合条件的元素。
let arr = [{value:1,label:1},{value:2,label:2},{value:3,label:3}];
console.log(arr.findLast(item=>{return item.value===2}));//Object { value: 2, label: 2 }
console.log(arr.findLast(item=>{return item.value===4}));//undefined
console.log(arr.findLastIndex(item=>{return item.value===3}));//2
六、fill():用于填充数组,并指定覆盖原有数组
console.log([1,2,3].fill("x"));//Array(3) [ "x", "x", "x" ]
console.log([1,2,3,4,5,6].fill("x",3,5));//Array(6) [ 1, 2, 3, "x", "x", 6 ]
七、遍历数组
1、entries()+for(of)
let arr =[11,21,31]
for (let i of arr.entries()){
console.log(i);
}
//Array [ 0, 1 ]
//Array [ 1, 2 ]
//Array [ 2, 3 ]
2、keys()+for(of)
let arr =[11,21,31]
for (let i of arr.keys()){
console.log(i);
}
//0
//1
//2
3、values()+for(of)
let arr =[11,21,31]
for (let i of arr.values()){
console.log(i);
}
//11
//21
//31
八、includes():判断某个元素是否在数组
let arr = [1,2,3]
console.log(arr.includes(2));//true
console.log(arr.includes(5));//false
扩展
1、arr.indexOf()的缺点
(1)是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。
(2)内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。
2、Map里的has()方法是找键;Set里的has()方法是找值。
九、flat()、flatMap():把数组里的多维(嵌套)数组变为指定维度数组(拉平)
let arr=[1,[3,[6,8]]]
console.log(arr.flat(1));//Array(3) [ 1, 3, [6,8] ]
console.log(arr.flat(2));//Array(4) [ 1, 3, 6, 8 ]
arr.flat(Infinity):实现无论嵌套多少层数组,全部转为一维数组。
let arr = [1,[2,[3,4,[5,6]]]]
console.log(arr.flat(Infinity));//Array(6) [ 1, 2, 3, 4, 5, 6 ]
arr.flat()可以跳过为数组的空位元素
console.log([1,,3,2,,2,,4].flat());//Array(5) [ 1, 3, 2, 2, 4 ]
十、at():实现数组的负索引(支持数组和字符串)
let arr = [1,2,3,4]
console.log(arr.at(-1));//4
let str = "Hello Wold!"
console.log(str.at(-1));//!
十一、对数组的操作
1、toReversed():颠倒数组成员位置【reverse】
使用reverse()产生的数组是引用指针
let arr=[1,1,2,2,3,3]
let arr2=arr.reverse()
arr2[0]="111"
console.log(arr);//Array(6) [ "111", 3, 2, 2, 1, 1 ]
使用toReversed()使用克隆的方式产生新数组
let arr=[1,1,2,2,3,3]
let arr2=arr.toReversed()
arr2[0]="111"
console.log(arr);//Array(6) [ 1, 1, 2, 2, 3, 3 ]
console.log(arr2);//Array(6) [ "111", 3, 2, 2, 1, 1
2、toSorted():数组排序【sort】
let arr = [1,0,23,4,2,2]
console.log(arr.toSorted());//Array(6) [ 0, 1, 2, 2, 23, 4 ]
3、toSpliced():指定位置删除元素或插入新元素【splice】
let arr = [1,2,3,4,5]
console.log(arr.toSpliced(0,2,"X"));//Array(4) [ "X", 3, 4, 5 ]
//指定下标0开始删除2个元素(1,2),并添加新元素"X"
4、with(index,value):指定位置元素替换【splice(index,1,value)】
let arr = [1,2,3,4,5]
console.log(arr.with(0,"X"));//Array(5) [ "X", 2, 3, 4, 5 ]
//把下标为0的元素1替换成“X”
以上方法会返回原数组操作后的拷贝
十二、数组的空位(某个位置没有任何值)
1、ES5: (1)forEach()、filter()、reduce()、every()、some()会跳过空位;
let arr = [1,2,,3,4,,]
arr.forEach((item,index)=>{
console.log("下标为",index,"元素为",item);
})
//下标为 0 元素为 1
//下标为 1 元素为 2
//下标为 3 元素为 3
//下标为 4 元素为 4
let arr = [1,2,,3,4,,]
arr.filter((item,index)=>{
console.log("下标为",index,"元素为",item);
})
//下标为 0 元素为 1
//下标为 1 元素为 2
//下标为 3 元素为 3
//下标为 4 元素为 4
let arr = [1,2,,3,4,,]
// some()判断是否至少存在一个元素为2,
console.log(arr.some(item=>item===2));//true
// every()判断每一个元素都为2
console.log(arr.every(item=>item===2));//false
(2)map()会跳过空位,但会保留这个值;
let arr = [1,2,,3,4,,]
arr.map(item=>{
console.log(item);
})
//1
//2
//3
//4
(3)join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串。
let arr =[1,,2,3]
console.log(arr.join(","));//1,,2,3
console.log(arr[1].toString());
//Uncaught TypeError: arr[1] is undefined
2、ES6会将空位转为undefined。