数组的扩展

扩展运算符

console.log(...[1, 2, 3])
// 1 2 3
//你甚至可以在后面放置表达式
const arr=[
    ...(x>0?['a']:[]),
    'b',
];
//替代apply方法
//ES5用法
var args=[0,1,2];
f.apply(null,args)
//ES6
let args=[0,1,2];
function f(x,y,z){}
f(...args);
// 将数组push到一起
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);
  • 复制数组
const a1 = [1, 2];
const a2 = a1;//只是复制了指针.修改a2会直接修改a1
//更好的方式:
const a1=[...a2];
//合并数组,不过实际上都是浅拷贝,都是对原有数组的引用
arr1.concat(arr1,arr2);//ES5
[...arr1,...arr2]
//使用扩展运算符解构时需要放在最后一位参数
const [first, ...rest] = ["foo"];//first为"foo",rest为[]
//可以把字符串转为真正的数组及识别四个字节的Unicode字符,因此遇到有4个字节的Unicode字符时最好都用扩展运算符改写
'x\uD83D\uDE80y'.length // 4
[...'x\uD83D\uDE80y'].length // 3

任何定义了遍历器接口的对象可以使用扩展运算符作为真正的数组,如下:

let nodeList = document.querySelectorAll('div');
let array = [...nodeList];
//可以自己定义迭代器
Number.prototype[Symbol.iterator] = function*() {
  let i = 0;
  let num = this.valueOf();
  while (i < num) {
    yield i++;
  }
}
console.log([...5]) // [0, 1, 2, 3, 4]
//注意普通对象是没有实现迭代器的

数组的空位

Array(3) // [, , ,]
0 in [undefined, undefined, undefined] // true
0 in [, , ,] // false
ES6中将空位转为undefined
Array.from(['a',,'b'])
// [ "a", undefined, "b" ]
for...of循环,copyWithin()也会遍历空位

Array.prototype.sort()排序是稳定的.

数组方法

  • Array.from()将类似数组的对象和可遍历的对象(Set和Map)转为真正的数组。
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']
使用了Iterator接口的数据结构就可以转为数组
Array.from('hello')
// ['h', 'e', 'l', 'l', 'o']
拥有length属性的对象可以使用Array.from转为数组,如:
Array.from({ length: 3 });
// [ undefined, undefined, undefined ]
//接收第二个参数来对每个元素进行处理后放进去
Array.from(arrayLike, x => x * x);
// 等同于
Array.from(arrayLike).map(x => x * x);
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]
//可以用Array.from把字符串转为数组,不会出现字符编码字节数的问题
function countSymbols(string) {
  return Array.from(string).length;
}

Array.of()

用于把一组值转为数组

Array.of(2)//[2]
//这是为了弥补构造函数的问题
Array() // []
Array(3) // [, , ,],如果只有一个参数是只能用来指定变量
Array(3, 11, 8) // [3, 11, 8]
使用[].slice.call(arguments)也可以实现

copyWithin()

使用Array.prototype.copyWithin(target, start = 0, end = this.length)

// 将3号位复制到0号位
[1, 2, 3, 4, 5].copyWithin(0, 3, 4)
// [4, 2, 3, 4, 5]
// -2相当于3号位,-1相当于4号位
[1, 2, 3, 4, 5].copyWithin(0, -2, -1)
// [4, 2, 3, 4, 5]
// 将3号位复制到0号位
[].copyWithin.call({length: 5, 3: 1}, 0, 3)
// {0: 1, 3: 1, length: 5}
// 将2号位到数组结束,复制到0号位
let i32a = new Int32Array([1, 2, 3, 4, 5]);
i32a.copyWithin(0, 2);
// Int32Array [3, 4, 5, 4, 5]
// 对于没有部署 TypedArray 的 copyWithin 方法的平台
// 需要采用下面的写法
[].copyWithin.call(new Int32Array([1, 2, 3, 4, 5]), 0, 3, 4);
// Int32Array [4, 2, 3, 4, 5]

数组的find()和findIndex()

find()用于找到符合条件的数组成员:
[1, 4, -5, 10].find((n) => n < 0)
参数:

[1, 5, 10, 15].find(function(value, index, arr) {
  return value > 9;
}) // 10
//找到NaN
[NaN].indexOf(NaN)
// -1
[NaN].findIndex(y => Object.is(NaN, y))
// 0

数组实例的fill()

fill()会不管数组中有没有值都进行填充,第二个和第三个参数指定填充起点和终点,填充的那个对象也一样是浅拷贝,所以改变一个会都改变.

遍历数组实例

可以使用for...of遍历,keys()是对键名遍历,values()对键值的遍历,entries()是对键值对的遍历。

for(let index of ['a','b'].keys())
for(let elem of ['a','b'].values())
for(let [index,elem] of ['a','b'].entries())
//或者使用next方法
let letter=['a','b','c'];
let entries=letter.entries();
entries.next().value

数组的includes()方法,返回bool值,判断是否存在

第二个参数指定起始位置
indexof()会对NaN误判,用于找到参数的第一个出现位置。
Map的has用于查键名,而Set的has方法用来查值的。

flat方法用于把多维的数组转为一维

[1, 2, [3, 4]].flat()//默认拉平一层,flat(3)可以拉平三层,会跳过空位
// [1, 2, 3, 4]
// flatMap,相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]
posted @ 2022-10-17 13:43  梦呓qwq  阅读(12)  评论(0编辑  收藏  举报