美文网首页
Array构造函数创建数组后map函数的注意事项

Array构造函数创建数组后map函数的注意事项

作者: revert | 来源:发表于2018-06-27 01:05 被阅读24次

    示例

    假设你需要生成一个从0到99的数组。你要怎么做呢?下面是一种解法:

    const arr = [];
    for (let i = 0; i < 100; i++) {
      arr[i] = i;
    }
    

    如果你和我一样,看到这种使用传统的for循环的方式会有点不大习惯了。事实上,我已经好多年不使用for循环写代码了。毕竟,各种高阶函数,像forEach, map, filter, reduce足以让我写出各种漂亮的代码。

    也许你还没有沉醉于函数式编程的美妙,那么你会认为上面的解法足矣。不过,如果你用过高阶函数编程,你也许就会想:一定还有更加优雅的实现方法。

    我的第一直觉就是:首选创建一个长度为100的空数组,然后由map用index去初始化每一个元素。在JavaScript中,你可以用Array构造函数来创建数组:

    const arr = Array(100);
    

    接下来你只需要用map就可以解决问题了:

    const arr = Array(100).map((_, i) => i);
    
    console.log(arr[0] === undefined);  // true
    

    可是,为什么第一个元素不是0而是undefined?

    解释

    为了理解为何没有生效,我需要首先讲清楚一个非常重要的技术点。在内部,JavaScript数组实际上是对象,对象里面的属性名是数字,对应数组的下标。举个例子:

    ['a', 'b', 'c']
    

    它实际上等价于:

    {
      0: 'a',
      1: 'b',
      2: 'c',
      length: 3
    }
    

    当你去访问数组的第0个元素的时候,实际上访问的是对象中属性名为0的元素。接下来我们会解释为何刚刚的代码没有效果。

    当你使用Array构造函数来新建一个数组,那么它会创建一个新的数组对象,并且将长度length设定为指定的值。但是,对象里面没有数组索引:

    {
      //no index keys!
      length: 100
    }
    

    当你去访问数组的第0个元素的时候,返回值为undefined。但并不是指第0个元素得值为undefined,而是当数组下标不存在的时候,默认的返回值。

    并且如果数组下标不存在的话,其实map函数并没有真正的对每一个元素执行操作。因为只有当下标存在的时候,map的回调函数才会执行。


    解法

    因此,我们只需要在数组对象中构造出数组的下标就可以了。最好的方法就是用展开运算符:

    const arr = [...Array(100)].map((_, i) => i);
    console.log(arr[0]);
    // 0
    

    使用展开运算符后的数组对象:

    {
      0: undefined,
      1: undefined,
      2: undefined,
      ...
      99: undefined,
      length: 100
    }
    

    就可以顺利使用map函数了。

    转自 FunDebug

    相关文章

      网友评论

          本文标题:Array构造函数创建数组后map函数的注意事项

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