我在Firefox-3.5.7/Firebug-1.5.3和Firefox-3.6.16/Firebug-1.6.2中观察到这一点

当我启动Firebug时:

var x = new Array(3) console.log (x) // [undefined, undefined, undefined] Var y = [undefined, undefined, undefined] console.log (y) // [undefined, undefined, undefined] Console.log (x.constructor == y.constructor) // true console.log ( X.map(函数(){返回0;}) ) // [undefined, undefined, undefined] console.log ( Y.map(函数(){返回0;}) ) // [0,0,0]

这是怎么回事?这是一个错误,还是我误解了如何使用新数组(3)?


当前回答

如果你这样做是为了方便地用值填充数组,由于浏览器支持的原因不能使用fill,并且真的不想做for循环,你也可以执行x = new array (3).join(".").split(".").map(…它会给你一个空字符串数组。

我不得不说,这很难看,但至少问题和意图传达得很清楚。

其他回答

在ECMAScript第6版规范。

new Array(3)只定义属性长度,不定义索引属性如{length: 3}。参见https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array-len步骤9。

[undefined, undefined, undefined]将定义索引属性和长度属性,如{0:undefined, 1: undefined, 2: undefined, length: 3}。参见https://www.ecma-international.org/ecma-262/6.0/index.html#sec-runtime-semantics-arrayaccumulation ElementList步骤5。

方法map, every, some, forEach, slice, reduce, reduceRight, Array的filter将通过HasProperty内部方法检查索引属性,因此new Array(3)。Map (v => 1)将不会调用回调函数。

更多详细信息,请参见https://www.ecma-international.org/ecma-262/6.0/index.html#sec-array.prototype.map

如何修复?

let a = new Array(3);
a.join('.').split('.').map(v => 1);

let a = new Array(3);
a.fill(1);

let a = new Array(3);
a.fill(undefined).map(v => 1);

let a = new Array(3);
[...a].map(v => 1);

ES6解决方案:

[...Array(10)]

但不能在typescript(2.3)上工作

如果你这样做是为了方便地用值填充数组,由于浏览器支持的原因不能使用fill,并且真的不想做for循环,你也可以执行x = new array (3).join(".").split(".").map(…它会给你一个空字符串数组。

我不得不说,这很难看,但至少问题和意图传达得很清楚。

数组是不同的。不同之处在于,new Array(3)创建了一个长度为3但没有属性的数组,而[undefined, undefined, undefined]创建了一个长度为3的数组和三个名为“0”、“1”和“2”的属性,每个属性的值都为undefined。你可以用in操作符看出区别:

"0" in new Array(3); // false
"0" in [undefined, undefined, undefined]; // true

这源于一个有点令人困惑的事实,即如果您试图在JavaScript中获取任何原生对象的不存在属性的值,它将返回undefined(而不是抛出错误,当您试图引用不存在的变量时就会发生这种情况),这与之前显式地将属性设置为undefined时得到的结果相同。

从map的MDC页面:

[…回调函数只对赋值的数组索引调用;[…]

[undefined]实际上应用了索引(es)上的setter,因此map将进行迭代,而new Array(1)只是初始化索引(es),默认值为undefined,因此map跳过它。

我相信这对于所有的迭代方法都是一样的。