Skip to content

Es6 为数组也拓展了一些方法。

1.创建数组

创建数组有两种方式:

  1. 字面量
  2. 构造函数

在本章,我们着重讨论下构造函数创建数组的这种方式。

Es5 中利用构造函数创建数组:

js
// 1.传入一个参数 且数据类型为number
var arr1 = new Array(3)
console.log(arr1) // [empty × 3]

// 2.存入一个参数 且数据类型为string
var arr2 = new Array('3')
console.log(arr2) // ['3']

// 3.传入多个参数 且第一个参数的数据类型为number
var arr3 = new Array(3, '3')
console.log(arr3) // [3, '3']

根据上例,我们能观察到在 Es5 中利用构造函数创建数组时,其结果有一些不统一。

Es6 为了尽可能消除这种歧义,提供了额外的方法。

1-1.Array.of()

Array.of 方法支持传入多个参数,但它不会把唯一的 number 类型入参设置成数组长度:

也就是说,相对于 Array 构造函数创建数组,它的创建结果更加规整。

js
// 1.传入一个参数 且数据类型为number
var arr1 = Array.of(3)
console.log(arr1) // [3]

// 2.存入一个参数 且数据类型为string
var arr2 = Array.of('3')
console.log(arr2) // ['3']

// 3.传入多个参数 且第一个参数的数据类型为number
var arr3 = Array.of(3, '3')
console.log(arr3) // [3, '3']

1-2.Array.from()

Array.from 方法可将类数组对象和可迭代对象转化为数组。

它的使用方式与展开运算符 ... 极其类似。

js
// 1.arguments
function fn () {
  console.log(Array.from(arguments)) // [1, 2, 3]
  console.log([...arguments]) // [1, 2, 3]
}
fn(1, 2, 3)

// 2.set
var set = new Set([1, 2, 3])
console.log(Array.from(set)) // [1, 2, 3]
console.log([...set]) // [1, 2, 3]

// 3.map
var map = new Map([['id', '19'], ['name', 'Tom']])
console.log(Array.from(map)) // [['id', '19'], ['name', 'Tom']]
console.log([...map]) // [['id', '19'], ['name', 'Tom']]

除了上述的基本用法之外,Array.from 还支持自定义处理每一项数据,及指定 this 指向:

js
var helper = {
  value: 1,
  add (v) {
    return v + this.value
  }
}
function fn () {
  console.log(Array.from(arguments, helper.add, helper))
}
fn('1', '2', '3') // ['11', '21', '31']

另外要注意的一点是,Array.from 会以迭代器数据为主:

js
// 对象本身是不可迭代的 但我们可以给它添加上自定义迭代器
var obj = {
  items: ['1', '2', '3'],
  *[Symbol.iterator] () {
    for (var i = 0; i < this.items.length; i++) {
      yield this.items[i]
    }
  }
}
console.log(Array.from(obj))
console.log([...obj])

2.为所有数组添加的新方法

Es6 也拓展了现有的数组方法。

2-1.find()与findIndex()

Es5 之前,由于没有对应的原生方法,所以检索数组比较麻烦。

Es5 当中增加了 indexOf()lastIndexOf() 方法,从而允许开发者在数组中查找特定值。

indexOf()lastIndexOf() 方法只能定向检索某个数值。不能进行更多的操作。

在此情况下,Es6 提供了 find()findIndex() 方法。

这两者的入参与 mapfilter 等方法一致。

TIP

  1. find() 方法的返回值是数组的目标值 value
  2. findIndex() 方法的返回值是数组的索引 index
js
var list = [10, 100, 1000]
// 1.find()
var value = list.find(item => item > 10)
console.log(value) // 100
// 2.findIndex()
var index =  list.findIndex(item => item > 10)
console.log(index) // 1

2-2.fill()

fill() 意为填充,它能定向覆盖数组当中的数据。

支持入参如下:

  1. value 填充值。该值会用来覆盖数组数据。
  2. startIndex 起始索引。覆盖时的数组起始索引。
  3. endIndex 结束索引。覆盖时的数组结束索引。(不包含该结束索引的数组项)。

fill()是变异方法,它会影响到原数组。

js
// 1.数组长度为0 调用fill方法 无效
var list = []
console.log(list.fill(1)) // []
// 2.数组有长度时 会自动填充元素至数组长度
list.length = 3
console.log(list.fill(1)) // [1, 1, 1]
// 3.数组当中有元素时 会将所有元素的值覆盖成fill的首位入参
list = [2, 1, 3, 4]
console.log(list.fill(1)) // [1, 1, 1, 1]
// 4.当你想定向覆盖时 可以指定fill的第二位入参
list = [2, 1, 3, 4]
console.log(list.fill(1, 2)) // [2, 1, 1, 1]
// 5.提供第三位入参 可以更加精确范围
list = [2, 1, 3, 4]
console.log(list.fill(1, 2, 3)) // [2, 1, 1, 4]

2-3.copyWithin()

copyWithin() 方法与 fill() 方法功能类似。

只不过 copyWithin 用来复制原数组的值。而 fill 方法则是复制自定义值。

copyWithin 也是变异方法。

参数如下:

  1. startPasteIndex 开始粘贴的索引。
  2. startCopyIndex 开始复制的索引,不设置时默认为 0
  3. endCopyIndex 结束复制的索引(不包含该位置自身)。startCopyIndex 截取后的数据进行二次截取。
js
// 1.开始从索引为1处粘贴 开始复制的起始索引为0
var list = ['1', '2', '3', '4', '5']
console.log(list.copyWithin(1)) // ['1', '1', '2', '3', '4']
js
// 2.开始为索引为1处粘贴 开始复制的起始索引为2
var list = ['1', '2', '3', '4', '5']
console.log(list.copyWithin(1, 2)) //  ['1', '3', '4', '5', '5']
js
// 3.['2', '3', '4', '5'] ['3', '4', '5'] ['3', '4']
var list = ['1', '2', '3', '4', '5']
console.log(list.copyWithin(1, 2, 3)) // ['1', '3', '4', '4', '5']

3.定型数组