(新的数组(10))。映射(函数(){返回1;})返回[,,,,,,,,,]…为什么?

3
我希望以下代码返回[1,1,1,1...]
(new Array(10)).map(function() { return 1;})

但是它返回[, , , , , ...]

此外,(new Array(10)).length == 10(new Array(10))[0] == undefined都是正确的。

对于z = function(){return 0;};,表达式z(undefined) === 0也是正确的。

然而我注意到[,,,,,,,,,,].map(function() { return 1; })也返回[,,,,....]

有人能解释为什么吗?

3个回答

7
我期望以下代码返回[1,1,1,1...]:
(new Array(10)).map(function() { return 1;})但它返回了[, , , , , ...]。
没错,因为new Array(10)创建了一个没有元素的数组,其长度为10,而 map仅迭代实际存在的元素。(是的,这确实令人惊讶。 :-) )
此外,(new Array(10)).length == 10(new Array(10))[0] == undefined都为true。再次正确,因为(再一次)new Array(10)没有在数组中放置任何元素,所以访问[0]将得到undefined
JavaScript的标准数组实际上并不是真正的数组,它们可以具有一个正数长度,而没有任何条目。它们是一种“稀疏”数组。
让我们看一个更简单的例子:
var a = new Array(10);
a[2] = 1;

这个数组包含一个元素,即索引为2的元素。在索引01以及3及以上的位置上没有元素,只是留下了空缺。你可以通过查询来确认:

console.log(0 in a); // "false"
console.log(1 in a); // "false"
console.log(2 in a); // "true"

JavaScript中的标准数组只是具有特殊行为的对象,这些特殊行为分配给length,分配给一类属性名称(宽松地说,是数字属性),并由Array.prototype支持。与此相反,较新的“类型化”数组如Int32Array等是传统意义上的真正的数组。

4

这个会起作用:

Array.apply(null, Array(10)).map(…
在线演示: http://jsfiddle.net/xXG5p/ 首先,您需要使数组变得稠密。使用new Array(n)可以创建一个稀疏数组。稀疏数组具有length属性,但是没有任何元素。因此,调用.map()不会迭代任何内容。
使用上面的代码,您将创建一个包含元素的稠密数组(值最初设置为null)。

其他人都在谈论为什么它行不通,而你却提供了解决方案。谢谢! - jsuddsjr

1
以下是Mozilla Developer Network关于Array.prototype.map的说明:

回调函数仅对已分配值的数组索引调用;它不会为已删除或从未分配值的索引调用。

当您调用new Array(10)时,您创建的Array认为它有10个元素,但它的索引都没有被赋值。以下是一个示例,说明如果您使用一个字面量数组,而没有为某些索引设置值,会发生什么:
[1, , 3].map(function () {return "a"})

你得到的值是:
[ 'a', , 'a' ]

因为在索引1处未分配任何值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接