我在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(…它会给你一个空字符串数组。

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

其他回答

我认为最好的解释方式是看看Chrome处理它的方式。

>>> x = new Array(3)
[]
>>> x.length
3

因此,实际发生的情况是new Array()返回一个长度为3的空数组,但没有值。因此,当您在技术上为空的数组上运行x.map时,不需要设置任何内容。

Firefox只是用undefined“填充”这些空槽,即使它没有值。

我不认为这是一个明显的错误,只是一种表现正在发生的事情的糟糕方式。我想Chrome的是“更正确”,因为它显示数组中实际上没有任何东西。

刚碰到这个。使用Array(n).map肯定会很方便。

数组(3)大致生成{length: 3}

[undefined, undefined, undefined]创建有编号的属性: {0:未定义,1:未定义,2:未定义,长度:3}。

map()实现仅作用于已定义的属性。

从map的MDC页面:

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

[undefined]实际上应用了索引(es)上的setter,因此map将进行迭代,而new Array(1)只是初始化索引(es),默认值为undefined,因此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时得到的结果相同。

下面是一个简单的实用方法:

简单地图

函数mapFor(toExclusive, callback) { Callback = Callback || function(){}; Var arr = []; For (var I = 0;i < toExclusive;我+ +){ arr.push(回调(i)); } 返回arr; }; var arr = mapFor(3,函数(i){返回i;}); console.log (arr);// [0,1,2] arr = mapFor(3); console.log (arr);// [undefined, undefined, undefined]

完整的示例

下面是一个更完整的例子(带有完整性检查),它也允许指定一个可选的起始索引:

function mapFor() { var from, toExclusive, callback; if (arguments.length == 3) { from = arguments[0]; toExclusive = arguments[1]; callback = arguments[2]; } else if (arguments.length == 2) { if (typeof arguments[1] === 'function') { from = 0; toExclusive = arguments[0]; callback = arguments[1]; } else { from = arguments[0]; toExclusive = arguments[1]; } } else if (arguments.length == 1) { from = 0; toExclusive = arguments[0]; } callback = callback || function () {}; var arr = []; for (; from < toExclusive; from++) { arr.push(callback(from)); } return arr; } var arr = mapFor(1, 3, function (i) { return i; }); console.log(arr); // [1, 2] arr = mapFor(1, 3); console.log(arr); // [undefined, undefined] arr = mapFor(3); console.log(arr); // [undefined, undefined, undefined]

倒计时

操作传递给回调函数的索引允许向后计数:

var count = 3;
var arr = arrayUtil.mapFor(count, function (i) {
    return count - 1 - i;
});
// arr = [2, 1, 0]