数组(len)初始值设定项中未定义的值

var a = Array(3); var b = [undefined,undefined,undefined]; 

是什么原因, a.mapb.map产生不同的结果?

 a.map(function(){ return 0; }); //produces -> [undefined,undefined,undefined] b.map(function(){ return 0; }); //produces -> [0,0,0] 

数组构造函数创build一个给定长度的数组。 它不会创build密钥。 Array.prototype.map的callback函数只对列表中的元素执行。
也就是说,与一个关键字(整数)0≤i< 长度有关的所有值。

  • Array(3)有零键,所以.map的callback从不被触发。
  • [void 0, void 0, void 0]有三个键,为其执行callback函数。

     Array(3).hasOwnProperty(0); // false [void 0, void 0, void 0].hasOwnProperty(0); // true 

MDN中提到了规范及其填充 。 在第47行, if (k in O) {表明不存在callback函数处理不存在的键。

来自MDN :

callback仅针对已赋值的数组的索引进行调用; 对于已被删除或从未被赋值的索引,不会调用它。

对于数组a ,你已经实例化一个长度为3的数组,但是没有赋值。 map函数找不到具有赋值的元素,所以它不会产生新的数组。

对于数组b ,你实例化了一个由3个元素组成的数组,每个元素的值都是undefined 。 map函数查找3个带有赋值的元素,并在新数组中为每个元素返回“0”作为新值。

a是一个没有元素的空数组,因此map函数生成没有元素的空数组(每个规范,只有当[[HasProperty]]为true时,map才会生成结果。) b是一个由三个元素组成的数组,三个元素的数组。

map只迭代现有的属性,而不是空的索引。

因此,如果你想要它的工作,你必须先填充数组。

有多种方式可以做到这一点,例如:

  • .fill() ,在ES6中引入

     console.log(new Array(3).fill().map(function(){ return 0; }));