数组的扩展

扩展运算符

含义

扩展运算符...,将数组转为用逗号分隔的序列。

log(...[1, 2, 3]); // 1 2 3

如果扩展运算符后面是一个空数组,不会产生任何效果。

log([...[], 1, 2, 3]); // [1, 2, 3]

只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错。

(...[1, 2, 3]); // Uncaught SyntaxError: Unexpected token ...

替代函数的 apply 方法

const args = [1, 2, 3];
function sum(a, b, c) {
  console.log(a + b + c);
}
// es5
sum.apply(null, args); // 6
// es6
sum(...args); // 6

利用 push 函数,将一个数组添加到另一个数组的尾部。

// es5
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
Array.prototype.push.apply(arr1, arr2);
log(arr1); // [1, 2, 3, 4, 5, 6]
// es6
let arr3 = [1, 2, 3];
let arr4 = [4, 5, 6];
arr3.push(...arr4);
log(arr3); // [1, 2, 3, 4, 5, 6]

扩展运算符的应用

1、复制数组

// es5
const arr = [1, 2, 3];
let arr2 = arr.concat(); // 浅拷贝
arr2.push(4);
log(arr2); // [1, 2, 3, 4]
log(arr); // [1, 2, 3]

// es6
const arr = [1, 2, 3];
let arr2 = [...arr]; // 或者 [...arr2] = arr; 浅拷贝
arr2.push(4);
log(arr2); // [1, 2, 3, 4]
log(arr); // [1, 2, 3]

2、合并数组

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const arr3 = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6] 浅拷贝

3、与解构赋值结合

const [first, ...rest] = [];
log(first); // undefined
log(rest); // []

如果用于数组赋值,只能放在参数的最后一位,否则会报错。

4、字符串

将字符串转成数组

略...

5、实现了 Iterator 接口的对象

// 给 Number 部署一个 Iterator 接口
Number.prototype[Symbol.iterator] = function*() {
  let i = 0;
  let num = this.valueOf();
  while (i < num) {
    yield i++;
  }
}
// 可以用扩展运算符将 5 转为 Number 实例后,转为数组
[...5]; // 5 4 3 2 1

类数组的对象,没有 Iterator 接口,就不能用扩展运算符来转数组。

可以用 Array.from() 来实现。

const arrayLike = {
  0: 'a',
  1: 'b',
  length: 2,
};
log(Array.from(arrayLike)); // ["a", "b"]

6、Map 和 Set 结构,Gegerator 函数

let map = new Map([
  [1, 'a'],
  [2, 'b'],
  [3, 'c'],
]);
map.keys(); // MapIterator {1, 2, 3}
[...map.keys()]; // [1, 2, 3]

Array.from()

将类数组对象(array-like object)和可遍历(iterable)对象转为真正的数组。

const arrayLike = {
  0: 'a',
  1: 'b',
  length: 2,
};
// es5
Array.prototype.slice.call(arrayLike); // ["a", "b"]
// es6
Array.from(arrayLike); // ["a", "b"]

将 DOM 操作返回的 NodeList 集合转为数组。

const pList = document.querySelectorAll('p');
log(pList); // NodeList(5) [p, p, p, p, p]
const pArray = Array.from(pList);
log(pArray); // (5) [p, p, p, p, p]

Array.from 还可以接受第二个参数,类似于数组的 map 方法,用于处理数组的每个元素。

const arrayLike = {
  0: 1,
  1: 2,
  length: 2,
};
log(Array.from(arrayLike, a => a * 2)); // [2, 4]

Array.of()

将一组值转换为数组。

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

copyWithin()

const array = [1, 2, 3, 4, 5, 6];
const newArray = array.copyWithin(0, 2); // 从第 0 个位置开始替换数据,数据读取开始位置为第 2 位--即数字3。
log(newArray); // [3, 4, 5, 6, 5, 6]

find() 和 findIndex()

可以接收第二个参数,用于绑定回调函数的 this 对象。

const array = [1, 2, 3, 4, 5, 6];
const index = array.findIndex(function(item) {
  return item > this.age;
}, {name: 'Wendy', age: 5});
console.log(index); // 5

fill()

使用给定值填充数组。

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

可以接受第二第三个参数,指定填充的起始和结束位置。

log([1, 2, 3, 4, 5, 6].fill(8, 2, 4)); // [1, 2, 8, 8, 5, 6]

entries() keys() values()

用于遍历数组,返回遍历器对象,可以用 for...of 遍历。

  • keys() 返回键名的遍历
  • values() 返回值的遍历
  • entries() 返回键值对的遍历

includes()

返回数组是否包含某个给定的值。

const arr = [1, 2, 3, 4, 5, 6];
log(arr.includes(3)); // true
log(arr.includes(3, 4)); // false 第二个参数表示从哪个位置开始查
log(arr.includes(3, -1)); // false 第二个参数表示从哪个位置开始查,负数表示倒数
log(arr.includes(5, -2)); // false 第二个参数表示从哪个位置开始查,负数表示倒数
log(arr.includes(3, -4)); // true 第二个参数表示从哪个位置开始查,负数表示倒数
log(arr.includes(3, -7)); // true 第二个参数表示从哪个位置开始查,负数表示倒数,超过数组的长度,就会重置为0

flat() flatMap()

flat() 将嵌套的数组变成一维数组,返回一个新数组,对原数组没影响。

const arr = [1, 2, 3, [4, 5, 6]];
log(arr.flat()); // [1, 2, 3, 4, 5, 6]
log(arr); // [1, 2, 3, Array(3)]

flat() 方法可以传入一个参数,表示要展开的层级。

const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9]]];
log(arr.flat(2)); // [1, 2, 3, 4, 5, 6, 7, 8, 9] 可以传入一个参数,表示要展开的层级
log(arr); // [1, 2, 3, Array(4)]

不管多少层都要展开的话,可以传入 Infinity。

const arr = [1, 2, 3, [4, 5, 6, [7, 8, 9, [10, 11, [12, [13]]]]]];
log(arr.flat(Infinity)); //[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] 传入 Infinity,展开所有层级
log(arr); // [1, 2, 3, Array(4)]

flatMap() 对数组每个对象执行一个函数,然后再执行 flat().

const arr = [1, 2, 3];
log(arr.flatMap(v => [v, v * 2])); // [1, 2, 2, 4, 3, 6]
// 相当于
log([[1, 2], [2, 4], [3, 6]].flat());

flatMap() 只能展开一层数组。

Last Updated: 6/12/2019, 12:10:49 AM