乐趣区

关于前端:数组的扩展和新增方法

残余运算符

残余运算符:... 变量
能够将数组的值解形成 单个单个的参数序列

console.log(...[1,2,3,4,5]);  // 1 2 3 4 5
let {a, b, ...z} = {a: 1, b: 2, c: 3, d: 4}
// a 1
// b 2
// z {c:3, d:4}

残余运算符是否为深拷贝的问题

1、残余运算符如果只有一层,是深拷贝

// 数组
let a = [1,2,3,4]
let b = [...a]
b[0] = 5
console.log(a);  // [1,2,3,4]
console.log(b);  // [5,2,3,4]
// 对象
let aa = {name:'东方'}
let bb = {...aa}
bb.name = '求败'
console.log(aa);  // {name:'东方'}
console.log(bb);  // {name:'求败'}

2、残余运算符如果有多层,数据是根本类型的,为深拷贝

let c = [1,2,3]
let d = [4,5,6]
let e = [...c,...d]
e[0] = 9
console.log(c); // [1, 2, 3]
console.log(d); // [4, 5, 6]
console.log(e); // [9, 2, 3, 4, 5, 6]

3、残余运算符如果有多层,对象、数组内的参数序列是援用类型的,为浅拷贝。
外部的援用类型对象其实复制了指针,所以为浅拷贝,根底类型为深拷贝。

let a2 = [{name:'西方'},5]
let b2 = [...a2]
b2[0].name = '不败'
b2[1] = 6
console.log(a2);  // [{不败},5]
console.log(b2);  // [{不败},6]

Array.from()

Array.from()能够将相似数组对象或者可遍历对象转为真正的数组。
须要留神的是:必须得有 length 属性才能够转换。

// 谬误的
   let ar = { 
        '0' : 'a',
        '1' : 'b',
        '2' : 'c',
     }
console.log(ar);  // {0: 'a', 1: 'b', 2: 'c'}
console.log(ar.length); // undefined
console.log(Array.from(ar));  // []
// 正确的
   let ar2 = { 
       '0' : 'a',
       '1' : 'b',
       '2' : 'c',
        length : 3
     }
console.log(ar2);  // {0: 'a', 1: 'b', 2: 'c', length: 3}
console.log(ar2.length);  // 3
console.log(Array.from(ar2));  // ['a', 'b', 'c']

任何具备 length 属性的都能够通过 Array.from() 转为数组

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

Array.from()第二个参数能够将转换后的数组的每个元素解决并返回

Array.from([1,2,3],(x)=> x + 1);  // [2,3,4]
Array.from('123',(x)=> x + 1);  // ['11', '21', '31']

Array.from()返回的是一个新数组

let arr3 = [1,2,3]
let arr4 = Array.from(arr3,x => x +1)
console.log(arr3);  // [1,2,3]
console.log(arr4);  // [2,3,4]

能够通过第二个参数判断数组中的值是否存在,如果数值不存在或者是false(假),则返回0

let arr5 = [1,,2,,3,false,true]
Array.from(arr5, n => n || 0);  // [1, 0, 2, 0, 3, 0, true]

Array.fo()

将一组值转换为数组

Array.of(1,2,3);  // [1,2,3]
Array.of(3);   // [3]

find()、findIndex()、findLast()

find()

数组办法,返回 符合条件 的第一个数组成员,未找到则返回undefined

let fi = [{id:1,name:'西方'},
      {id:2,name:'不败'},
      {id:3,name:'东方不败'}
     ]
let back = fi.find(el => el.id == 2)
let back2 = fi.find(el => el.id == 4)
console.log(back);  // {id: 2, name: '不败'}
console.log(back2);  // undefined

findIndex()

数组办法,返回 符合条件 的数组 下标 ,未找到则返回-1,返回的下标从0 开始

let fi2 = [{id:1,name:'西方'},
     {id:2,name:'不败'},
     {id:3,name:'东方不败'}
    ]
let back3 = fi2.findIndex(el => el.id == 2)
let back4 = fi2.findIndex(el => el.id == 4)
console.log(back3);  // 1
console.log(back4);  // -1

findLast()

数组办法,从数组尾部开始向前查看,返回符合条件的那一项

let fi3 = [{id:1,name:'西方'},
     {id:2,name:'不败'},
     {id:3,name:'东方不败'}
   ]
let back5 = fi2.findLast(el => el.id == 2)
let back6 = fi2.findLast(el => el.id == 4)
console.log(back5);  // {id: 2, name: '不败'}
console.log(back6);  // undefined

findLastIndex()

数组办法,从尾部开始向前查看,返回合乎的以后项的下标,从 0 号位开始,未找到返回-1

let fi4 = [{id:1,name:'西方'},
    {id:2,name:'不败'},
    {id:3,name:'东方不败'}
  ]
let back7 = fi2.findLastIndex(el => el.id == 2)
let back8 = fi2.findLastIndex(el => el.id == 4)
console.log(back7);  // 1
console.log(back8);  // -1

fill()

将给定的参数填充数组

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

第二个参数和第三个参数别离为填充的开始地位和完结地位的前一位,从 0 号位开始

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

这里填充的是从数组的第 2 号位开始,第 4 号位的前一位完结


entries()、keys()、values()

keys 对键名遍历

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

values 对键值遍历

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

entries 键值对遍历

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

includes()

includes() 判断数组中是否存在对应的值,返回 truefalse

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

flat()、flatMap()

flat()

flat()能够将嵌套的数组‘拉平’,变成一维数组

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

flat()的参数代表须要 拉平的层数 ,这里嵌套了3 层数组,拉平 3

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

Infinity为深度拉平,不论嵌套多少层都会转换为一维数组

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

flatMap()
相当于 map 函数,对数组的每一项进行迭代操作,并返回新数组,不会影响原数组

[1,2,3].flatMap(el => el + 1);  // [2,3,4]

at()

at()参数为数组的索引
负数 从数组 头部 索引 0 开始
正数 从数组 尾部 索引 -1 开始,-1代表数组尾部的第一个值

[1,2,3,4,5].at(2);  // 3
[1,2,3,4,5].at(-2); // 4
'hello world'.at(2); // l
'hello world'.at(-3); // r

超出范围返回undefined

[1,2,3,4,5].at(-20); // undefined
[1,2,3,4,5].at(20); // undefined

toReversed()、toSorted()、toSpliced()、with()

一般的数组办法会影响原数组,例如:push()、pop()、shift()、unshift()
当初有一个提案,对数组进行操作时,不影响原数组 ,返回一个原数组的拷贝
别离有四个:toReversed()、toSorted()、toSpliced()、with()
这四个办法对应的是数组原有的办法,用法截然不同,只是不会扭转原数组,返回一个新数组

原数组办法 新数组办法
reverse() toReversed()
sort() toSorted()
splice() toSpliced()
splice(index, 1, value) with(index, value)

group()、groupToMap()

group() 分组函数,能够将原数组进行分组,并返回分组后的对象,相当于是给符合条件的数组成员取名分组

let gr = [1,2,3,4,5]
let g = gr.group(el=> el > 3 ? 'greater' : 'less')
console.log(g);  // {greater: [4,5], less: [1,2,3] }

groupToMap() 分组函数相当于 map 函数,对数组的每一项进行迭代操作,并返回新数组,不会影响原数组。


数组空位

数组的空位是指数组的某一个地位没有任何值

console.log(Array(3));  // [empty x 3]也就是[,,,]

须要留神的是,空位并不是 undefined,某一个地位的值等于undefined,其实是有值的,空位是没有任何值,in 运算符能够直观的看到这一点。

 console.log(0 in [undefined,undefined,undefined]);  // true
 console.log(0 in [,,,]);  // false

下面代码阐明,第一个数组的 0 号位是有值的,第二个数组的 0 号位没有值的

ES5办法对空位的解决是不统一的,但 大多数状况 下会 疏忽空位

forEach()、filter()、reduce()、every()、some()都会跳过空位
map() 会跳过空位,但会保留这个值
join()toString()会将空位视为 undefined,而undefinednull会被解决成空字符串""

ES6 则是将空位转换成undefined,ES6 的办法不会疏忽空位

console.log(Array.from([1,,3]));  //  [1, undefined, 3]
console.log(...[1,,3]);  //  1, undefined, 3

entries()、keys()、values()、find()findIndex() 会将空位解决成undefined

es6两个非凡的办法

// copyWithin()会连空位一起复制
console.log([,'a','b',,].copyWithin(2,0));  // [,"a",,"a"]

 // fill 会将空位视为失常位
 console.log([4,,6].fill(1));  //  1, 1, 1

js的数组空位解决并不对立,应该防止在数组中呈现空位


sort()

sort()排序是数组中一个 == 十分重要 == 的办法

let arr = [2,3,6,4,5,1]
// 升序
console.log(arr.sort((a,b) => a - b));  // [1,2,3,4,5,6]
// 降序
console.log(arr.sort((a,b) => b - a));  // [6,5,4,3,2,1]

按条件排序

let arr2 = [{id:1,name:'名称 1'},{id:3,name:'名称 3'},{id:2,name:'名称 2'},{id:6,name:'名称 6'},{id:4,name:'名称 4'},{id:5,name:'名称 5'}]

let so = arr2.sort((a,b)=>{return a.id - b.id});

console.log(so);
// [{id: 1, name: '名称 1'},{id: 2, name: '名称 2'},{id: 3, name: '名称 3'},{id: 4, name: '名称 4'},{id: 5, name: '名称 5'},{id: 6, name: '名称 6'}]

对于 sort() 的具体阐明,请看另一篇:sort()排序以及多个属性数组对象排序(按条件排序)


案例源码:https://gitee.com/wang_fan_w/es6-science-institute

如果感觉这篇文章对你有帮忙,欢送点亮一下 star 哟

退出移动版