前言
本文主要介绍ES6中关于数组扩展的一些知识点,具体包括以下内容:
扩展运算符 ...
将数组转为用逗号分隔的参数序列。
console.log(...[1,2,3,4,5])
// 1 1 2 3 4 5
复制代码
- 用于函数调用时传参,可与普通参数结合使用;
function add (x, y, z) {
console.log(x + y + z)
}
add(...[1, 2, 3]) // 6
add(1, ...[2, 3]) // 6
add(1, ...[1, 2, 3]) // 4
复制代码
- 替代函数的apply方法;
// ES5 的写法
Math.max.apply(null, [1, 2, 3])
// ES6 的写法
Math.max(...[1, 2, 3])
// 等同于
Math.max(1, 2, 3);
复制代码
- 复制合并数组(对象为引用复制);
- 复制数组
let arr1 = [1, 2, 3, 4, 5, {name: 'Memory'}]
let arr2 = [...arr1]
arr2 // [1, 2, 3, 4, 5, {name: "Memory"}]
arr1 === arr2 // false
arr2[0] = 'test'
arr2[5].name = 'doubleMeng'
arr1 // [1, 2, 3, 4, 5, {name: "doubleMeng"}]
arr2 // ["test", 2, 3, 4, 5, {name: "doubleMeng"}]
复制代码
- 合并数组
let arr1 = [{ foo: 1 }]
let arr2 = [1, 2, 3]
let arr3 = ['a', 'b', 'c']
let arr4 = [...arr1, ...arr2, arr3]
arr4 // [{foo: 1}, 1, 2, 3, ["a", "b", "c"]]
arr4[0] === arr1[0] // true
复制代码
- 与解构赋值结合,用户生成数组;
let [first, ...rest] = [1, 2, 3, 4, 5]
first // 1
rest // [2, 3, 4, 5]
复制代码
let [first, ...rest] = [];
first // undefined
rest // []
复制代码
let [first, ...rest] = [1];
first // 1
rest // []
复制代码
- 只能放在参数的最后一位,否则会报错。
let [first, ...second, last] = [1, 2, 3, ,4, 5]
// Uncaught SyntaxError: Rest element must be last element
复制代码
- 将字符串转为数组;
[...'12345'] // ["1", "2", "3", "4", "5"]
复制代码
-
任何定义了
Iterator
接口的对象,都可以用扩展运算符转为真正的数组。比如函数arguments、document.getElementsByTagName('div')、Set、Map、Generator函数返回值等。
- 定义了Iterator接口
function test () {
console.log([...arguments]) // [1, 2, 3, 4, 5]
console.log(arguments instanceof Array) // false
console.log([...arguments] instanceof Array) // true
}
test(1, 2, 3, 4, 5)
复制代码
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
])
let arr = [...map.keys()]
arr // [1, 2, 3]
复制代码
- 未定义Iterator接口
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
[...arrayLike];
// Uncaught TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
复制代码
注意
- 如果放在
()
中,会被解析为函数调用。如果这时不是函数调用,则会报错;
(...[1,2,3,4,5])
// Uncaught SyntaxError: Invalid destructuring assignment target
复制代码
- 如果是一个空数组,则不会产生任何效果;
console.log(...[]) // 无效果
[1, ...[]] // [1]
复制代码
- 可以放表达式;
let x = 1
[
...(x > 0 ? ['a', 'b', 'c'] : [1, 2, 3]), 'test'
]; // ["a", "b", "c", "test"]
```
```
let y = -1
[
...(y > 0 ? ['a', 'b', 'c'] : [1, 2, 3]), 'test'
]; // [1, 2, 3, "test"]
复制代码
创建数组
主要讲将其他类型数据转换为数组,可用的方法有Array.from()
、Array.of()
Array.from(target, [map], [this])
用于将类似数组的对象(array-like object)和可遍历(iterable)对象转为真正的数组
参数:
-target: 目标对象,为类数组或可遍历对象;
-[map]: 函数,作用类似于map,用来对每个元素进行处理,将处理的值放入返回的数组;
-[this]: 用来绑定函数(map)的this对象。
- 类似数组的对象(array-like object),拥有length属性;
- 常见场景:DOM选择器返回的NodeList集合、函数的arguments。
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr = Array.from(arrayLike) // ["a", "b", "c"]
复制代码
function add () {
Array.from(arguments) // [1, 2, 3]
Array.from(arguments, (x) => x * x) // 1 4 9
}
add(1, 2, 3)
复制代码
- 可遍历(iterable)的对象(例如Set、Map、String等)。
let set = new Set([1, 2, 3) // {1, 2, 3}
Array.from(set) // [1, 2, 3]
Array.from([set, (x) => x * x) // [1, 4, 9]
```
```
let str = 'abc' // "abc"
Array.from(str) // ["a", "b", "c"]
复制代码
Array.of(arg1, arg2, ...)
- 用于将一组值,转换为数组;
Array.of(1, 2, 3) // [1, 2, 3]
Array.of(1) // [1]
复制代码
- 弥补Array()的不足。
- Array()
Array(3) // [empty × 3] 被当做length处理
Array('3') // ["3"]
复制代码
- Array.of()
Array.of(3) // [3] 被当做元素处理
Array.of('3') // ["3"]
复制代码
查找元素
用于在当前数组中查找指定目标,可用的方法有includes()
、find()
、findIndex()
。
includes(target, [start])
是否包含给定的目标值,返回一个Boolean值。
参数:
-target: 要寻找的目标值;
-[start]: 开始寻找的位置。
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[undefined, NaN, null].includes(undefined) // true
[undefined, NaN, null].includes(NaN) // true
[undefined, NaN, null].includes(null) // true
复制代码
起始位置为负数,则表示倒数的位置。如果该值得绝对值大于数组长度,则从第0位开始查找。
[1, 2, 3].includes(2, 1) // true
[1, 2, 3].includes(2, 2) // false
[1, 2, 3, 4, 5].includes(4, -2) // true
[1, 2, 3, 4, 5].includes(3, -2) // false
[1, 2, 3, 4, 5].includes(3, -100) // true 从第0位开始查找
复制代码
find(callback, [this])
找出第一个符合条件的值,所有没有找到该元素,则返回undefined。
参数:
-callback: 回调函数;
-[this]: 用来绑定回调函数的this对象。
let arr = [-2, -1, 0, 1, 2]
arr.find(item => item > 0) // 1
arr.find(item => item > 5) // undefined
复制代码
findIndex(callback, [this])
找出第一个符合条件的值的下标,所有没有找到该元素,则返回-1。
参数:
-callback: 回调函数;
-[this]: 用来绑定回调函数的this对象。
let arr = [-2, -1, 0, 1, 2]
arr.findIndex(item => item > 0) // 3
arr.findIndex(item => item > 5) // -1
复制代码
填充数组
将其他数据填充至该数组,可用的方法有copyWithin()
、fill
。
copyWithin(target, [start], [end])
将指定位置的成员复制到其他位置,将原数组修改并返回。
参数:
-target: 从该位置开始替换数组,如果为负值,则表示倒数;
-[start]: 从该位置读取数据,默认为0,如果为负数,则表示倒数;
-[end]: 从该位置前停止读取数据,默认等于数组长度,如果为负数,表示倒数。
[1, 2, 3, 4, 5].copyWithin(0, 3) // [4, 5, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(1, 3) // [1, 4, 5, 4, 5]
[1, 2, 3, 4, 5].copyWithin(0, -3, -1) // [3, 4, 3, 4, 5]
[1, 2, 3, 4, 5].copyWithin(1, -3, -2) // [1, 3, 3, 4, 5]
复制代码
fill(value, [start], [end])
使用给定值,填充一个数组。
参数:
-value: 要填充的值;
-[start]: 开始填充的位置;
-[end]: 结束位置。
[1, 2, 3, 4, 5].fill('test') // ["test", "test", "test", "test", "test"]
[1, 2, 3, 4, 5].fill('test', 2, 4) // [1, 2, "test", "test", 5]
复制代码
遍历数组
遍历数组,返回一个遍历器对象,可用的方法有entries()
、 keys()
、 values()
。
keys()
遍历键名
for (let index of ['a', 'b', 'c', 'd', 'e'].keys()) {
console.log(index) // 0 1 2 3 4
}
复制代码
values()
遍历键值
for (let item of ['a', 'b', 'c', 'd', 'e'].values()) {
console.log(item) // a b c d e
}
复制代码
entries()
遍历键值对
for (let [index, item] of ['a', 'b', 'c', 'd', 'e'].entries()) {
console.log(index, item) // 0 "a" 1 "b" 2 "c" 3 "d" 4 "e"
}
复制代码
打平数组
将数组打平,可用的方法有flat()
、 flatMap()
。
flat([n])
该方法会跳过空位。
参数:
-[n]: 打平n层嵌套,默认为1,打平任意层可使用Infinity。
[1, 2, [3, [4, 5]]].flat() // [1, 2, 3, [4, 5]]
[[1, , [3, [4, 5]]].flat(2) // [1, 3, 4, 5]
[1, [2, [3, [4, [5]]]]].flat(Infinity) // [1, 2, 3, 4, 5]
复制代码
flatMap(func, [this])
对数组的每一个成员执行一个函数,然后对返回值执行flat(1)方法;
返回新数组,不改变原数组。
参数:
-func: 遍历函数,该函数可接受三个参数:当前数组成员、当前数组成员的位置、原数组;
-[this]: 绑定遍历函数的this。
[1, 2, 3].flatMap(item => item * 2) // [2, 4, 6]
[1, 2, 3].flatMap(item => [item * 2]) // [2, 4, 6]
[1, 2, 3].flatMap(item => [[item * 2]]) // [[2, 4, 6]] 默认只能展开一层
复制代码
参考
小结
本文主要介绍了ES6中对于数组的一些扩展,其中包括扩展运算符(...
)、创建数组(Array.from()
Array.of()
),查找元素(find()
findIndex()
includes()
)、填充数组(copyWithin()
fill()
)、遍历数组(keys()
values()
entries
)、打平数组(flat()
flatMap()
)等方面做主要阐述。
感谢阅读,如有问题,欢迎指正。