美文网首页
快速填充数组里的思考

快速填充数组里的思考

作者: 袁韩 | 来源:发表于2016-05-23 21:19 被阅读127次

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

    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。完美!

    相关文章

      网友评论

          本文标题:快速填充数组里的思考

          本文链接:https://www.haomeiwen.com/subject/iyoarttx.html