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

wva*_*aal 17 javascript arrays

我最近在SO上发现了以下代码片段,以帮助快速填充具有默认值的数组:

Array.apply(null, new Array(3)).map(function() {return 0;});
Run Code Online (Sandbox Code Playgroud)

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

Array.apply(null, [undefined, undefined, undefined]).map(function() {return 0;});
Run Code Online (Sandbox Code Playgroud)

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

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]
Run Code Online (Sandbox Code Playgroud)

然而,其中出现了两个奇怪之处:

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

谁能解释这种行为?

Ber*_*rgi 16

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

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

如果sparseArr的最后一个术语未定义

不.您忘记了尾随的逗号,这是自EcmaScript 5以来的可选项.实际上它只[1]相当于[1,](两者都有一个长度1).

要获得稀疏的"插槽",您必须添加其他commata:

[] // empty array
[,] // empty array
[,,] // [undefined x 1]
[,,,] // [undefined x 2]
Run Code Online (Sandbox Code Playgroud)

如果sparseArr只包含一个术语,则结果denseArr等于[undefined x N]

考虑调用该apply方法意味着什么:

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)
Run Code Online (Sandbox Code Playgroud)

并且您知道Array构造函数在使用单个数字参数调用时所执行的操作 - 它会创建该长度的稀疏数组...