在javascript中访问超出其大小的数组

时间:2014-05-26 09:08:06

标签: javascript arrays

我在一本特定的书中读到,JavaScript中的数组可以容纳4,294,967,295个项目,如果数量超过该数量,则会抛出异常。 我使用以下代码尝试了该功能:

var a = ["a","b","c"];
a[4294967300] = "d";
console.log(a[4294967300]);

显示输出" d"并且没有例外或错误。我在这里错过了什么吗?有人可以对这个主题有所了解并分享一些关于JavaScript中的最大数组项目以及与之相关的各种场景的知识吗?

3 个答案:

答案 0 :(得分:6)

数组不必包含从0N的所有项目,以包含索引为N的项目。

这是因为当漏洞太大​​时,JavaScript引擎中的数组可以切换到字典模式,这些数组称为稀疏数组(vs 密集数组)。

了解这种区别很重要,因为实施正在泄漏一点:性能。您应该阅读以下主题:http://www.html5rocks.com/en/tutorials/speed/v8/

但是对于从2 32开始的索引, sebcap26 是正确的,由于索引被处理为字符串这一事实有区别。这种区别很重要,可以通过记录a.length来验证:您将看到长度不受此类元素的影响。 本身没有异常或错误,但它使得无法使用常规数组操作,例如迭代到长度或使用mapfilter等数组函数(这些函数会忽略大于数字索引限制的索引。

答案 1 :(得分:5)

如果我理解ECMAScript specifications,则不在[0 .. 2 ^ 32-1]中的索引将转换为字符串并用作Object键,而不是用作数组索引。

  

当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2 ^ 32-1时,属性名P(以String值的形式)是数组索引。

答案 2 :(得分:2)

尝试运行此代码:小提琴http://jsfiddle.net/vXtfE/

var a = ["a","b","c"];
a[4294967300] = "d";
console.log(a.length);
console.log(a);
console.log(a[4294967300]);

您将看到此输出:

3 
["a", "b", "c", 4294967300: "d"] 
d 

初始项目存储为数组元素,但对于大型索引,存储将更改为基于散列的稀疏数组。因此,在你的情况下,它是两者的混合。

对此有很好的解释:

Why is array.push sometimes faster than array[n] = value?