【问题标题】:Why does Array.apply(null, [args]) act inconsistently when dealing with sparse arrays?为什么 Array.apply(null, [args]) 在处理稀疏数组时行为不一致?
【发布时间】:2014-04-08 23:12:02
【问题描述】:

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

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

鉴于Array构造函数和apply方法的行为,上面的sn-p也可以改写成这样:

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]

然而,其中出现了两个奇怪的地方:

  1. 如果sparseArr 的最后一个术语未定义,则该术语不会映射到denseArr
  2. 如果sparseArr 仅包含一个词(例如sparseArr = [1])或单个词后跟一个未定义的单个尾词(例如sparseArr = [1,]),则生成的denseArr 等于[undefined x 1]

谁能解释这种行为?

【问题讨论】:

    标签: javascript arrays


    【解决方案1】:

    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 个元素的数组的奇怪行为的第二点。在给出的示例中,如果sparseArr = [1]denseArr 将等于[undefined x 1]。你能解释一下这种行为吗?
    • 呃,我一开始没有注意到第二点,因为您将第一个行为混入了它的描述中……答案已更新。
    • 哇,“逗号”的复数形式是“逗号”。呵呵。
    【解决方案2】:

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

    如果数组中有两个或多个连续的非尾随逗号,则它们的内容设置为未定义。

    注意:由于数组中的undefined 在 IEnull。

    当 sparseArr 包含一个项目时,您会得到令人惊讶的结果,这是因为 Array 有两个不同的构造函数:如果您传递多个参数,它会创建一个具有该序列的数组,如果您传递一个数字,它会创建一个长度数组"number" 用 undefined 填充。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-25
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多