是一个长度不可用的新JavaScript数组吗?

mae*_*ics 24 javascript

根据MDN文档,new Array(length)我可以初始化具有给定长度的数组:

var a = new Array(10);
a.length; // => 10
a; // => [undefined x 10]
Run Code Online (Sandbox Code Playgroud)

但是,显然我不能使用诸如map(...)新数组之类的方法,即使以其他方式构造的数组工作正常:

a.map(function() { return Math.random(); });
// => [undefined x 10] -- wtf?
[undefined, undefined].map(function() { return Math.random(); });
// => [0.07192076672799885, 0.8052175589837134]
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

我从这个经验(并在网上搜索)中了解到,具有长度的数组构造函数是一个无法解释的行为的黑洞,但ECMA 262规范是否提供了解释?

Ori*_*iol 19

new Array(10)不返回填充10 undefined秒的数组.相反,它返回一个没有元素的数组,并且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
Run Code Online (Sandbox Code Playgroud)

因此,ECMAScript 5数组方法会跳过那些不存在的属性.具体地,当它们从迭代0length,他们检查[[HasProperty]]阵列的内部方法.

您可以使用ECMAScript 6 Array.prototype.fill(可以进行polyfilled)轻松修复它:

new Array(10).fill().map(Math.random);
Run Code Online (Sandbox Code Playgroud)

  • @DontVoteMeDown如果你要构建一个庞大的数组并告诉浏览器它将拥有多少元素,浏览器可以在内存中保留空间.增加每个元素插入时的大小可能会更慢. (3认同)
  • 会说同样的,但你打败了我. (2认同)
  • 啊,所以看起来语言混淆了"长度"和"容量"(尽管随后的`push(...)`将插入索引"length + 1"(wtf)?<sigh>似乎像这只是语言中一个经过深思熟虑的部分. (2认同)