快速填充数组里的思考

用一行代码,快速填充一个数组

function fillArray(length, placeholder) {
  return Array.apply(null, Array(length)).map(()=>placeholder)
}

然而用下面的语句却不可以

Array(length).map(()=>placeholder)

Array(length)返回的结果与预想不一样

检查Array(length)的返回结果,发现其,是一个长度为length的数组,从0length-1都未定义。使用var arrWithHoles = Array(3)var arrWithHoles = [, , ,]等效。而我们预想中这个数组应该是var arr = [undefined,undefined, undefined]

两者的差别好比是var foo = {0: undefined}; console.log(foo[0])var foo = {}; console.log(foo[0])的差别

那些数组中未定义的索引,姑且称之为hole

使用Array.prototype.map遍历一个带有hole的数组,map方法会自动过滤hole。这是应该的,因为map不知道未定义的索引是什么(不可能凭空猜想吧),它只知道遍历的数组有多长,已定义的索引是什么,哪怕这些索引的值是undefined

apply与map函数工作方式不同

Array内置遍历函数有些会跳过hole,比如forEachmap,有些会报错,比如reduce,有些似乎没有影响,比如every

Function.prototype.apply的作用机制与Array内置函数不同。apply要求两个参数,第二个参数argsArray必须是一个数组。在Array.apply(null, Array(length))里,Array(length)应该经历了类似于如下的处理

var argsArray = Array(length)
var ret = []
var i
for (i = 0; i < argsArray.length; i++) {
  ret[i] = argsArray[i]
}

所以Array.apply(null, Array(length))返回的结果是一个长度为length的数组,从0到length-1的值都为undefined。

map方法知道这个数组从0到length-1都有定义。虽然这些索引的值都是undefined,但是这不重要。重要的是map知道它应该处理这些索引,因为这些索引都被声明了,然后取它们的undefined值及其他信息,运行map函数,返回一个新的数组。

最后Array.apply(null, Array(length)).map(()=>placeholder)返回的结果就是一个长度为length的数组,从0到length-1索引的值都为placeholder。完美!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容