数组(len)初始值设定项中未定义的值
var a = Array(3); var b = [undefined,undefined,undefined];
是什么原因, a.map
和b.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; }));