为什么Array.apply(null,[args])在处理稀疏数组时不一致?

时间:2014-04-08 23:12:03

标签: javascript arrays

我最近发现了以下snippet of code on SO以帮助快速填充具有默认值的数组:

Array.apply(null, new Array(3)).map(function() {return 0;});

鉴于Array构造函数和apply方法的行为,上面的代码片段也可以这样重写:

Array.apply(null, [undefined, undefined, undefined]).map(function() {return 0;});

在处理您希望使用默认值填充的稀疏数组时,此技术也很有用:

var sparseArr = [3,,,4,1,,],
    denseArr = Array.apply(null, sparseArr).map(function(e) {
      return e === undefined ? 0 : e;
    });

// denseArr = [3,0,0,4,1,0]

然而,其中出现两个奇怪之处:<​​/ p>

  1. 如果sparseArr的最终字词未定义,则该字词未映射到denseArr
  2. 如果sparseArr只包含一个术语(例如sparseArr = [1])或单个术语后跟一个尾随未定义的术语(例如sparseArr = [1,]),则生成的denseArr等于[undefined x 1]
  3. 任何人都可以解释这种行为吗?

2 个答案:

答案 0 :(得分:15)

  

new Array(3) [...]也可以重写为[undefined, undefined, undefined]

否 - 正如您刚才所见,数组构造函数创建稀疏数组,因此应将其重写为[,,,]

  

如果sparseArr的最终术语未定义

不。您忘记了自EcmaScript 5以来可选的尾随逗号。实际上[1]只相当于[1,](两者的长度均为1)。

要获得稀疏的“插槽”,您必须添加其他逗号:

[] // empty array
[,] // empty array
[,,] // [undefined x 1]
[,,,] // [undefined x 2]
  

如果sparseArr只包含一个字词,则生成的denseArr等于[undefined x N]

考虑调用apply method

的含义
Array.apply(null, [3,,4,1]) ≡ Array(3, undefined, 4, 1)
Array.apply(null, [3,4]) ≡ Array(3, 4)
Array.apply(null, [1]) ≡ Array(1)

你知道Array constructor在使用单个数字参数调用时的作用 - 它会创建一个具有该长度的稀疏数组......

答案 1 :(得分:3)

自ECMA 262以来,您可以在数组中使用尾随逗号。它的存在不会以任何方式修改数组的内容。

如果数组中有两个或多个连续的非尾随逗号,则其内容将设置为undefined。

注意:由于数组中的undefined在IE&lt; 9中具有非标准行为,我会避免在那里使用它。请改用null

当sparseArr包含一个项目时,你有惊人的结果,因为Array有两个不同的构造函数:如果你传递多个参数,它会创建一个带有该序列的数组,如果你传递一个数字,它会创建一个长度数组&#34;数&#34;充满了未定义。

new Array(1, 2, 3)
=> [1, 2, 3]

new Array(2)
=> [undefined, undefined]