14
[undefined, undefined, undefined].map(function(val, i) { return i });

返回 [0, 1, 2],而

Array(3).map(function(val, i) { return i });

返回 [未定义,未定义,未定义]。

为什么?

4

5 回答 5

13

在第一种情况下,您定义初始化了一个包含三个undefined值的新数组,而在第二种情况下,您 定义了一个可能长度为 3的数组。

new Array(3)和你一样:

var arr = [];
arr.length = 3;

结果,.length隐式定义了属性,.map()方法可以对分配在内存中的数组进行迭代,该数组基本上保存零定义的项目(即纯空)。

于 2013-02-13T14:29:03.487 回答
4

您正在声明指向未定义对象的指针undefined。因此,[undefined]创建一个指向未定义的指针数组。 new Array(3)创建一个未定义指针数组,这些指针不会被数组原型方法(包括.map)循环。

MDN 参考。该变量undefined实际上是在分配一个值,即使它指向undefined.

于 2013-02-13T14:29:28.833 回答
1

Array(3)只需要一个空数组并手动为其分配一个长度:

> a = []
[]
> a.length = 3
3
> a
[ , ,  ]

这与手动构造包含未定义元素的数组不同:

> a = [undefined, undefined, undefined]
[ undefined, undefined, undefined ]


Array的MDN 文档准确地解释了发生了什么:

如果传递给 Array 构造函数的唯一参数是介于 0 和 2 32 -1(含)之间的整数,则会将新的空 JavaScript 数组及其长度设置为该数字。如果参数是任何其他数字,则会引发 RangeError 异常。

所以数组被初始化为一个空数组[]。这解释了为什么map不处理任何数组元素,因为没有。


几个例子可能会有所帮助。当使用它初始化数组时,Array(3)它是空的,所以map没有什么可以迭代:

> Array(3)
    .map(function(val, i) { console.log(i); return i; });
[ , ,  ]

将其与以下示例进行比较,您可以看到每个中间数组值都输出到控制台:

> [undefined, undefined, undefined]
    .map(function(val, i) { console.log(i); return i; });
0
1
2
[ 0, 1, 2 ]
于 2013-02-13T14:32:08.260 回答
1

正如@VisioN提到的, Array(3) 已定义但未初始化。有趣的是,您可以通过 Array.apply 传递未初始化的数组,并对其进行初始化。我用它来填充数组:

Array.apply(null, Array(3)).map(function(val,i) { return i; });
// [0, 1, 2]
于 2013-02-14T15:37:00.177 回答
0
<script type="text/javascript">
 test();
 test2();

function test() {
   [undefined, undefined, undefined].map(function(val, i) { console.log("un: " + val + "/" + i); return i; });
 }

 function test2() {
    Array(3).map(function(val, i) { console.log("no: " + val + "/" + i); return i; });
 }
</script>

test() 函数返回:

un: 未定义/0 un: 未定义/1 un: 未定义/2

test2() 函数不返回值;

  • test() 你有一个包含 3 个值的对象(未定义)
  • test2() 有一个长度为 3 的空数组
于 2013-02-13T14:32:28.043 回答