根据MDN documentation for new Array(length)
,我可以初始化具有给定长度的数组:
var a = new Array(10);
a.length; // => 10
a; // => [undefined x 10]
然而,显然我不能在新数组上使用map(...)
之类的方法,即使以其他方式构造的数组工作正常:
a.map(function() { return Math.random(); });
// => [undefined x 10] -- wtf?
[undefined, undefined].map(function() { return Math.random(); });
// => [0.07192076672799885, 0.8052175589837134]
为什么会这样?
我从这次经验(并在网上搜索)中了解到,具有长度的数组构造函数是一个无法解释的行为的黑洞,但ECMA 262规范是否提供了解释?
答案 0 :(得分:19)
new Array(10)
不会返回填充10 undefined
s的数组。相反,它返回一个没有元素的数组,length
属性为10
。
看到区别:
var arr1 = new Array(1),
arr2 = [undefined];
arr1.length === arr2.length; // Both are `1`
arr1[0] === arr2[1]; // Both are `undefined`
arr1.hasOwnProperty(0); // false
arr2.hasOwnProperty(0); // true
因此,ECMAScript 5数组方法会跳过那些不存在的属性。具体来说,当他们从0
迭代到length
时,他们会检查数组的[[HasProperty]]
内部方法。
您可以使用ECMAScript 6 Array.prototype.fill
(可以是polyfilled)轻松修复它:
new Array(10).fill().map(Math.random);