在回答这个问题(Difference between [Object, Object] and Array(2))时,我遇到了一些我以前没有意识到的JavaScript数组中的某些东西(具有讽刺意味的是,考虑到我在微软的Chakra引擎中使用Arrays)。
如果我将其输入Chrome的JavaScript控制台......
var x = Array(2);
var y = [undefined, undefined];
var z = [,];
...然后在查询x
,y
和z
变量时,我分别获得此输出:
> 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]
?答案 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的成员被称为“被删除”。