ES6 的数组新增扩展

1. 扩展运算符 ...

扩展运算符实现的是浅拷贝,修改了引用指向的值会同步反映到新数组。

扩展运算符可以与解构赋值结合,用于生成数组:

const [first, ...rest] = [1, 2, 3, 4, 5];
// first = 1, rest = [2, 3, 4, 5]

const [first, ...rest] = [];
// first = undefined, rest = []

const [first, ...rest] = ["foo"];
// first = "foo", rest = []

将扩展运算符用于数组赋值时,只能放在参数最后一位,否则报错:

const [...butLast, last] = [1, 2, 3, 4, 5];       // 报错
const [first, ...middle, last] = [1, 2, 3, 4, 5]; // 报错

可以将字符串转为真正的数组:

[...'hello']; // ['h', 'e', 'l', 'l', 'o']

定义了 Iterator 接口的对象都可以用扩展运算符转为真正的数组:

const nodeList = document.querySelectorAll('div');
const array = [...nodeList];

const map = new Map([[1, 'one'], [2, 'two'], [3, 'three']]);
[...map.keys()]; // [1, 2, 3]

没有 Iterator 接口的对象使用扩展运算符会报错。

2. Array.from()

将两类对象转为真正的数组:

  • 类数组对象(有 length 属性)
  • 可遍历(iterable)的对象(含 ES6 新增的 Set 和 Map)
const arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 };
Array.from(arrayLike); // ['a', 'b', 'c']

Array.from({ length: 3 }, (_, i) => i + 1); // [1, 2, 3]

还可以接受第二个参数,对每个元素处理后放入返回数组。

3. Array.of()

将一组值转换为数组:

Array.of(3, 11, 8); // [3, 11, 8]
Array.of();          // []
Array.of(undefined);  // [undefined]

对比 Array() 的怪异行为:

Array();       // []
Array(3);      // [, , ,](长度为 3 的稀疏数组)
Array(3, 11);  // [3, 11]

4. 实例方法

方法说明
copyWithin(target, start?, end?)在数组内部将一段序列复制到另一位置
find(fn) / findIndex(fn)按回调查找首个匹配元素 / 索引
fill(value, start?, end?)用固定值填充一段区间
entries() / keys() / values()返回对应迭代器
includes(item, from?)是否包含某元素(NaN 也能命中)
flat(depth?) / flatMap(fn)数组扁平化 / 扁平化前先 map

5. 数组的空位

数组的某一个位置没有任何值,就是空位。ES6 明确将空位转为 undefined,涉及:Array.from、扩展运算符、copyWithin()、fill()、entries()、keys()、values()、find() 和 findIndex() 等。

建议日常书写避免出现空位。

6. 排序稳定性

Array.prototype.sort 在 ES2019 之后被规定为稳定排序(SameV8 / v8 / SpiderMonkey 等主流引擎均已实现),即相等元素的相对顺序在排序前后保持不变。

来源整理自:我的有道云笔记