前言

ES6 对数组进行了一些扩展,包括原型方法的扩展和一些实例的运用

Array 类上的扩展

Array 是一个类,也可以看做一个函数,他的返回值是一个数组

1
Array(x, y, z) // [x, y, z]

但是,如果只有一个参数,并且参数是数字,那么返回有 n 个空位的数组

1
Array(7) // [empty x 7]

Array.of()

为了解决上面的这个问题,在 ES6 中扩展了这个新的方法,在参数是一个数字的时候返回的依然是一个数组

1
Array.of(7) // [7]

Array.from()

Array.from() 方法用于将两类对象转为真正的数组:类似数组的对象,和可遍历对象(包括 ES6 新增的数据结构setmap

1
Array.from('123') = ['1', '2', '3']
1
2
3
4
5
6
7
let arrayLike = {
0: 'a',
1: 'b',
2: 'c',
}

Array.from(arrayLike) // ['a', 'b', 'c']

数组实例上扩展的方法

copyWithin()

数组实例的copyWhthin() 方法会在当前数组内部指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组,也就是说,这个方法会修改当前的的数据

  • 语法:它接受 3 个参数,这三个参数都应该是数值,如果不是数值,那么会自动转成数值
    • target(必选):从该位置开始替换数据
    • start(可选):从该位置开始读取数据,默认为零,如果为负数,表示倒数
    • end(可寻):到该位置停止读取数据,默认等于数组长度,如果为负数,表示倒数。
1
Array.prototype.copyWithin(target, (start = 0), (endnote = this.length))
  • 例子:
1
2
3
4
5
let ary = [1, 2, 3, 4, 5, 6, 7, 8]

ary.copyWithin(4, 2, 4) // [1, 2, 3, 4, 3, 4, 7, 8]
// 继续替换,原数组的length不变,如果有超出部分,会自动会截取
ary.copyWithin(3, 2) // [1, 2, 3, 3, 4, 3, 4, 7]

fill()

fill() 方法使用给定值填充一个数组。

1
2
let ary = ['a', 'b', 'c']
ary.fill(7) = [7, 7, 7]

fill() 方法还可以接收第二个和第三个参数,用于指定填充的起始位置和结束位置

1
2
let ary = ['a', 'b', 'c', 'd', 'e']
ary.fill(7, 1, 3) // ['a', 7, 7, 'd', 'e']

上面的代码表示,fill() 方法从 1 号位开始想原数组填充 7,到 3 位置之前结束,你可以简单记为:包前不包后 ,基本上所有数组实例上的方法,参数是从索引 n 到索引 m 的都是 包含 n 不包含 m。

filter()

filter() 表示过滤,遍历数组,根据返回值去过滤原数组,并返回一个新数组,原数组不变

1
2
3
4
5
6
7
8
let ary = ['a', 1, 2, 3, 'a']

let ary2 = ary.filter(function (item, index) {
//如果返回true就留下当前项,false不留下
return typeof item === 'number'
})

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

find()和 findIndex()

数组实例的find()方法用于找出第一个符合条件的数组成员,他的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为 true 的成员,然后返回该成员,如果没有符合条件的成员,则返回 undefined。注意,他只返回第一个找到的值

1
2
3
let ary = [1, 2, -2, 3, 4]

ary.find((n) => n < 0) // -2

findIndex()find() 类似,只不过返回的是索引值,如果全部都不符合,返回 -1。

1
2
3
let ary = [1, 2, -2, 3, 4]

ary.findIndex((n) => n < 0) // 2

includes()

Array.prototype.includes() 方法返回一个布尔值,表示某个数组是否包含给定的值,与字符串includes() 方法类似。

这个方法的第二个参数表示搜索的起始位置,默认为零,如果第二个参数为负数,则表示倒数,如果这时他大于数组的长度(比如参数为 -4 ,数组长度为 3),则会重置为从 0 开始。

1
2
3
let ary = [1, 2, 3]
ary.includes(1, 2) // false
ary.includes(1, -1) // true

every()

也是一个遍历的方法,遍历数组,如果每一项都返回 true ,最后结果为 true, 只要有一个为 false ,结果为 false

1
2
3
4
let ary = [1, 2, 3, 4, 5]
ary.every(function (item) {
return typeof item === 'number'
}) // true
1
2
3
4
let ary = [1, 2, 3, 4, 'a']
ary.every(function (item) {
return typeof item === 'number'
}) // false

some()

遍历数组,只要有一项返回 true ,最后结果为 true, 只有全部为 false 时 ,结果为 false

1
2
3
4
let ary = [1, 2, 3, 4, 'a']
ary.some(function (item) {
return typeof item === 'number'
}) // true

reduce(),reduceRight()

reduce()表示迭代,比如我们求和的时候可以用这个方法.他的第二个参数,会作为初始的 prev

1
2
3
4
5
let ary = [1, 2, 3, 4, 5]
ary.reduce(function (prev, item) {
// prev 上一次的返回值,item 当前项
return prev + item
}, 10) // 输出:25

reduceRight()reduce()类似,只不过是从右往左开始。

entries(),key(),values()

他们都返回一个遍历器对象,可以用 for…of 循环遍历,唯一的区别在于,key() 是对键名的遍历,values() 是对键值的遍历, entries() 是对键值对的遍历

1
2
3
4
5
6
7
let ary = ['a', 'b']

for (let index of ary.key()) {
console.log(index)
}
// 0
// 1
1
2
3
4
5
6
7
let ary = ['a', 'b']

for (let elem of ary.values()) {
console.log(elem)
}
// 'a'
// 'b'
1
2
3
4
5
6
7
let ary = ['a', 'b']

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

数组的空位

数组的空位指数组的某一个位置没有任何值,比如Array 构造函数返回的数组都是空位。

1
Array(3) // [, , ,]

注意:空位不是 undefined,一个位置的值等于 undefined依然是有值的,空位是没有任何值的,in 运算符可以说明这一点

1
2
0 in [undefined, ndefined, undefined] // true
0 in [, , ,] // false

上面的代码说明,第一个数组的 0 号位置有值,但第二个数组没有值。

ES5 中对空位的处理不一致,大多数情况下会忽略空位

  • forEach()filter()every()、和 some() 会跳过空位
  • map() 会跳过空位,但会保留这个值
  • join()toString() 会将空位视为undefined,而undefinednull 会被理解成空字符串。
1
2
3
4
5
[, 'a'].forEach((x, i) => console.log(i))   // 1

[, 'a'].map(x => 1) // [, 1]

[, 'a', undefined, null].join('#') // '#a##'

ES6 中明确将空位转为undefined

1
Array.from(['a', , 'b']) // ['a', undefined, 'b']

扩展运算符

扩展运算符是三个点(…),他如同 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。

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

因此可以替代数组的apply 方法

1
2
3
4
// ES5
Math.max, apply(null, [14, 3, 77])
// ES6
Math.max(...[14, 3, 77])

扩展运算符的一些应用

  • 合并数组
1
2
3
4
// ES5
[1, 2].concat(more)
// ES6
[1, 2, ...more]
  • 与解构赋值结合
1
2
3
4
// ES5
a = list[0], rest = list.slice(1)
// ES6
[a, ...rest] = list
  • 字符串
1
2
;[...'hello']
// ['h', 'e', 'l', 'l', 'o']

参考资料:

《ES6 标准入门》(第 3 版) 阮一峰著