[undefined×2]是什么意思,为什么它与[undefined,undefined]不同?

时间:2017-06-07 05:20:12

标签: javascript

在回答这个问题(Difference between [Object, Object] and Array(2))时,我遇到了一些我以前没有意识到的JavaScript数组中的某些东西(具有讽刺意味的是,考虑到我在微软的Chakra引擎中使用Arrays)。

如果我将其输入Chrome的JavaScript控制台......

var x = Array(2);
var y = [undefined, undefined];
var z = [,];

...然后在查询xyz变量时,我分别获得此输出:

> x
< [undefined × 2]
<    length: 2

> y
< [undefined, undefined] (
<    0: undefined
<    1: undefined
<    length: 2

> z
< [undefined × 1]
<    length: 1

MDN's relevant documentation代表Array(arrayLength)[]文字语法状态:

  

如果传递给Array构造函数的唯一参数是一个整数,则返回一个新的JavaScript数组,其length属性设置为该数字(注意:这意味着一个arrayLength个空插槽数组,而不是实际未定义的插槽值)。如果参数是任何其他数字,则抛出RangeError异常。

我注意到文档没有进一步阐述“槽”的概念 - 我假设它们将它用作“数组元素”的同义词(我知道JavaScript数组可以是稀疏数组,有一个不同的内部表示,但这不应该影响消费者看到它们的方式 - 假设JavaScript数组和对象无论如何都是对各种数据结构的抽象。)

MSDN上的相关文档没有提供Array函数或Array-literal []语法的edge-case参数。

所以我的问题是:

  • undefined × 2是什么意思?
  • 为什么Array(2)评估为[undefined × 2]而不是[undefined, undefined]
  • 为什么[,]length: 1

为了回答我自己的问题,我咨询了the ECMA-262 7.0 specification on Array Literals。关于 elided 数组文字元素(强调我的)有一个有趣的注释:

  

可以在元素列表的开头,中间或末尾省略数组元素。每当元素列表中的逗号前面没有AssignmentExpression(即开头的逗号或另一个逗号后面的逗号)时,缺少的数组元素会增加数组的长度并增加后续元素的索引。 未定义Elided数组元素。如果在数组的末尾省略了元素,则该元素不会影响数组的长度。

所以粗体部分至少回答了我的第三个问题:如果最后一个元素是“缺失”那么它就不存在了,如果一个非终端元素没有值,那么它就是undefined 。所以这些表达式是等价的:

[a,]   --> [a]
[a,b,] --> [a,b]
[a,,b] --> [a,undefined,b]

因此

[,]    --> [undefined]
[,,]   --> [undefined,undefined]

所以我在Chrome中试过这个:

> var a = [,,];
> a
> [undefined × 2]
>    length: 2

这是出乎意料的!根据元素省略的明确规则,我认为[,,]等同于[undefined,undefined],但Chrome认为[,,]相当于Array(2)(注意没有定义索引器) ,给它与案例y)相同的结果。

所以我的第四个问题:

  • 为什么[,,]相当于Array(2)而不是[undefined,undefined]

1 个答案:

答案 0 :(得分:2)

  

undefined×2是什么意思?

控制台显示某些开发人员根据某些输入确定的有用消息。它在任何意义上都不应被视为规范性的,在某些情况下会产生误导。声明:

var x = Array(2);

创建一个变量 x 并指定一个长度为2的新数组。没有任何意义上的“空槽”。它相当于:

var x = [,,];

(注意旧的IE有一个错误,上面创建了一个长度为3而不是2的数组)。您可以将其视为一个对象:

var x = {length: 2};

可以添加的属性数量决不受设置长度的限制。但是,设置现有数组的长度将删除索引等于或高于新长度的所有成员。

话虽如此,实现可以自由地为“长度”的索引分配空间,这在某些情况下似乎是性能提升,但并未指定为ECMA-262所要求的。

  

为什么Array(2)评估为[undefined×2]而不是[undefined,undefined]?

见上文,控制台只是试图提供帮助。根本没有未定义的成员,只有一个长度为2的数组。对于记录,IE 10显示:

[undefined, undefined]

由于上述原因也具有误导性。它应该显示[,,]

  

为什么[,]有一个长度:1?

这称为elision,它是array initializer或数组文字的一部分。它以与以下相同的方式创建“缺失”成员:

var x = [];
x[0] = 0;
x[2] = 2;

在索引1处没有成员,相当于:

var x = [0,,2];

再次注意到旧的IE将[,]解释为长度为2.索引1的成员被称为“被删除”。