数组的扩展

185 阅读3分钟

扩展运算符

扩展运算符: ... ,如同 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

扩展运算符后还可以放置表达式。

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

如果将扩展运算符用于数组赋值,则只能将其放在参数的最后一位,否则会报错。

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

function f(a, b, c, x, y, z) {}
let args = [2, 3, 4];
f(-1, ...args, 0, ...[2]);

let arr = [
    ...(x > 0 ? ['a'] : []),
    'b'
];

console.log([...[], 2]); // [2]

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

Array.from()

该方法用于将类似数组的对象(如 DOM 操作返回的 NodeList 集合、函数内部的 arguments 对象)、可遍历对象(包括 Set 和 Map 结构)转为真正的数组。任何有 length 属性的对象,都可以通过 Array.from 方法转为数组。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
let arr1 = Array.from(arrayLike); // ['a', 'b', 'c']

Array.from('hello'); // ['h', 'e', 'l', 'l', 'o']

let arrSet = new Set(['a', 'b']);
Array.from(arrSet); // ['a', 'b']

Array.from() 方法可以接受第二个参数,用来对每个元素进行处理,将处理后的值放入返回的数组。

Array.from([1, 2, 3], (x) => x * x); // [2, 4, 6]
Array.from([null, [], NaN], (x) => typeof x); // ['object', 'object', 'number']

Array.of()

该方法用于将一组值转为数组。主要是弥补 Array() 的行为不统一的不足。

Array.of(3, 2121, 32); // [3, 2121, 32]
Array.of(3); // [3]

Array(); // []
Array(3); // [, , ,]
Array(3, 11, 8); // [3, 11, 8]

数组实例的 copyWithin()

该方法会在当前数组的内部将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。接受 3 个参数:

  • target(必选):从该位置开始替换数据
  • start(可选):从该位置开始读取数据,默认为0,如为负数表示倒数
  • end(可选):到该位置停止读取数据,默认等于数组长度,如为负数表示倒数。
[1, 2, 3, 4, 5].copyWithin(0, -2, -1) // [4, 2, 3, 4, 5]

数组实例的 find() 和 findIndex()

这两个方法可以发现 NaN

// indexOf() 方法内部使用 === 判断,会导致 NaN 的误判
[NaN].indexOf(NaN) // -1
[NaN].findIndex(y => Object.is(NaN, y)) // 0

数组实例的 fill()

fill 方法使用给定值填充整个数组,可以接受第二个和第三个参数,指定填充开始的位置和结束的位置

['a', 'b', 'c'].fill(2, 1, 2) //['a', 2, 'c']

数组实例的 entries()、keys()、values()

  • etries():对数组键名的遍历

  • keys():对数组键值的遍历

  • values():对数组键值对的遍历

这三种方法都返回一个遍历器对象,可用 for...of 循环遍历。

也可以手动调用遍历器对象的 next 方法进行遍历

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

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

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

let letter = ['a', 'b', 'c'];
let entries = letter.entries();
console.log(entries.next().value); // [0, 'a']
console.log(entries.next().value); // [1, 'b']
console.log(entries.next().value); // [2, 'c']

数组实例的 includes()

该方法判断数组内是否有某个值,返回一个布尔值。可接收第二个参数,表示开始搜索的位置。

注意与 Map 和 Set 数据结构的 has 方法进行区分:

  • Map 结构的 has 方法用来查找键名

  • Set 结构的 has 方法用来查找值的

数组的空位

数组的空位是指某一个位置没有任何值(不包括 undefined 和 null),比如 [ , , ]。 es5 对空位处理很不一致,大多数情况下回忽略空位,如 forEach()、filter()、every() 和 some() 会跳过空位。ES6 则是明确将空位转为 undefined,如扩展运算符(...)、Array.from()、copyWithin()。

由于空位处理机制非常不统一,建议避免出现空位