JavaScript数组是关联数组吗?

6
例如,如果我执行a[1000000]=1;,它会使用内存来存储1000000个元素还是仅用于这一个元素?

相关:https://dev59.com/CnNA5IYBdhLWcg3wIqTr - Pindatjuh
4
看起来你在这里提出了两个非常不同的问题:标题中是它们是否是关联数组,文本中是它们是否是稀疏数组。事实上,JS数组的这两个方面是正交的(即稀疏性与关联性无关)。 - Tomalak
1
参见:https://dev59.com/cnI-5IYBdhLWcg3wCzxn - Christian C. Salvadó
4个回答

8
在ECMAScript标准(§15.4)中,数组的唯一特殊之处在于length属性会自动更新(以及一堆Array特定的原型函数):

数组对象对某些属性名称给予特殊处理。当且仅当ToString(ToUint32(P))等于PToUint32(P)不等于232−1时,属性名P(以字符串值的形式)是一个数组索引。
...
每个数组对象都有一个length属性,其值始终为小于232的非负整数。length属性的值在数值上大于每个名称为数组索引的属性的名称;...

除此之外,数组只是一个对象,这意味着它可以被视为一个关联数组,尽管你不应该这样做
现在的JS引擎应该检测数组是密集还是非常稀疏,并在内部使用线性或关联数组进行切换。在您的情况下,JS引擎不会分配一百万个元素。

+1 - 感谢您引用了规范的相关部分。我会相应地调整我的答案。 - Tomalak

7

会创建1,000,000个元素吗?

不会,数组是稀疏的,但它们的索引将是持久的。编辑:实际上,它们的稀疏性取决于具体实现,在a[1000000] = 1的情况下保持它们稀疏似乎是合乎逻辑的。

var a = [1, 2, 3, 4];
var x = a[1]; // -> x := 2

delete a[1];
var y = a[1]; // -> y := undefined

a[9] = 10;
var y = a[8]; // -> z := undefined

JavaScript数组是否是关联数组?

JavaScript数组是关联数组的一个子集(索引必须为整数,如KennyTM的回答所示)。而JavaScript对象则是完全的关联数组:

var o = { "key1": "value1", "key2": "value2" };
var i = "key2";
var v = o[i]; // -> v := "value2"

1
它们是否稀疏很可能取决于实现方式。我敢猜测未定义的值在中间的这些值会在当前的实现方式下被初始化并占用内存。 - Matti Virkkunen
@Matti:我对澄清这一点的定义/规范很感兴趣。思考一下,人们可以将固定的索引->值连接解释为关联性。 - Tomalak
4
数组是具有字符串和数字键的对象。和所有对象一样,它们是可关联的。浏览器通常还为数组中的数字键提供优化,但这是内部实现问题,不属于语言的一部分。 - bobince
@bobince:感谢您的澄清。这使得很多事情变得清晰明了。 - Tomalak
1
一个数组的 length 属性和成员函数忽略除了整型索引元素以外的任何数组属性。如果你向一个数组添加 [0],[1] 和 ["str"] 索引,则长度为 2(索引 0 和 1),通过 slice() 复制该数组将得到一个没有原始 "str" 属性的数组。如果需要在 Javascript 中使用关联数组,请使用对象。没有使用数组的好处,或者仅仅因为它表面上看起来可以作为关联数组而认为它是一个关联数组。 - Josh Townzen
显示剩余4条评论

1

在某些情况下,您可以使用对象字面量作为一种“关联数组”:

var object = {
  "first": "1",
  "second": "2",
  "third": "3",
  "fourth": "4"
};
object.fifth = "5";
object.["sixth"] = "6";

但它有其局限性... 没有神奇的“长度”参数,并且您无法访问每个数组都具有的方法。

0

JS数组是自动增长的。在空数组上将a[100]设置为1会用“undefined”填充前99个元素。


4
实际上没有任何东西被填充。这就是为什么不仅仅是第一个元素会成为未定义的(与用未定义填充不同),而是所有元素(除了a[100])都将是未定义的。 - Miguel Ventura
4
展示差异:a[1]=undefined。现在,a.length===2a['0']===undefineda[1]===undefined,但是尽管 '1' in atrue'0' in a 却为 false - bobince

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接