Array构造的数组使用map为什么失效?

译者按: Array函数构造的数组没有初始化索引,没法使用map函数。javascript

为了保证可读性,本文采用意译而非直译。另外,本文版权归原做者全部,翻译仅用于学习。前端

示例

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

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']
复制代码

它实际上等价于:app

{
  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

Fundebug专一于JavaScript、微信小程序、小游戏BUG监控,自从2016年双十一正式上线,Fundebug已经服务了一年半时间,累计处理了5亿+错误事件,获得了众多知名用户的承认。Fundebug支持主流前端框架的bug监控,欢迎各位老铁体验!

相关文章
相关标签/搜索