项目中偶尔会有生成数组序列( [1, 2, 3, 4, ....]
) 的需求,一般思路是先生成一个对应长度 n 的数组,然后利用数组的 map
方法返回 index
去生成数组序列,下面介绍几种方式(假设 n 为 10):
1. Function.prototype.apply()
方法
Array.apply(null, { length: 10 }).map((_, i) => i)
Array.apply(null, { length:10 })
会初始化一个包含 10 个 undefined
数组, map
一下即可。
2. Array(arrayLength)
构造函数
Array(10).toString().split(',').map((_, i) => i)
Array(10).join(',').split(',').map((_, i) => i)
Array(10).fill().map((_, i) => i)
Array(10)
构造出的数组只有 length
属性,各数组元素没有初始化,是 empty
状态,无法迭代,所以需要借助其他方法先填充下。
3. Array.prototype.keys()
方法
[...Array(10).keys()]
Array(10).keys()
会返回包含数组中每个索引键的迭代器对象,所以直接用数组展开方法即可。
4. Array.from()
方法
Array.from(Array(10).keys())
Array.from({ length: 10 }).map((_, i) => i)
Array.from()
可以从一个迭代器对象或者类数组对象创建一个数组。
还可以利用这个方法的第二个参数,直接添加 mapFn
方法:
Array.from(Array(10), (_, i) => i)
5. Array.prototype.map()
和 Function.prototype.call()
结合
Array.apply(null, {length: 10}).map(Function.call, Number)
Array.from({length: 10}).map(Number.call, Number)
Array(10).fill().map(Number.call, Number)
首先初始化一个包含 n 个 undefined
组成的数组, 对于 map(Function.call, Number)
,先来看 Array.prototype.map
方法的参数,该方法接收一个生成新数组元素的 callback
函数和一个可选的 thisArgs
作为 callback
函数执行时的 this
指向。因此,执行这个 map
方法就等于对数组的每个元素执行
(Function.call).call(Number, undefined, index, array)
其中, undefined
, index
, array
是 callback
的参数。接下来需要化简下这个表达式,在这里 Funtion.call
就是一个普通的函数,所以执行第二个 call
, Number
作为 thisArgs
赋给 Function.call
函数,就相当于执行 Number.call
,加上参数,表达式就变成:
Number.call(undefined, index, array)
这表示执行 Number
构造函数,this 指向 undefined
,而对 Number
构造函数来说,只有第一个参数有意义,所以进一步化简为:
Number(index)
于是便可得到一个数组序列。
Function.call
和 Number.call
都指向了 Function.prototype.call
,因此 map
函数的第一个参数只要是 call
方法就可以了。关键是第二个参数的设置,决定了第一个 call
的调用方式,比如:
Array.from({length: 10}).map(Function.call, String)
返回
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']