字符串作为数组键

49

当使用字符串作为数组键时,console显示该数组不包含这些已声明的值,并且在按此值迭代时,键为字符串的值未显示,尽管我可以获取它们的值。

>> var arr = [ 0, 1, 2, 3 ];
   undefined

>> arr["something"] = "aught";
   "aught"

>> arr
   [0, 1, 2, 3]

>> arr["something"]
   "aught"

>> for( var i = arr.length; i--; console.log( arr[ i ] ) );
   3
   2
   1
   0

我了解数组是JavaScript引擎中实现了某种“枚举”接口的对象。

最有趣的是,解释器既没有抛出警告也没有报错,因此我花了一些时间寻找数据可能丢失的地方。

2个回答

105

在JavaScript中有两种类型的数组:标准数组和关联数组。

  • [ ] - 标准数组 - 仅支持基于0的整数索引
  • { } - 关联数组 - JavaScript对象,其中键可以是任何字符串

因此,当您定义:

var arr = [ 0, 1, 2, 3 ];

你正在定义一个标准数组,其中索引只能是整数。当你执行arr["something"]时,由于something(你用作索引的内容)不是整数,因此你基本上是在为arr对象定义属性(在 JavaScript 中,所有内容都是对象)。但你并没有向标准数组中添加元素。


2
@abuduba,因为没有任何问题 :-) 你的代码是完全有效的JavaScript。由于你混合了两种类型的数组,所以对读者来说有些模糊,但它是有效的。当没有问题时,为什么要让解释器指示出错呢? - Darin Dimitrov
35
这主要是一个术语问题,但是JavaScript通常不把{}称为关联数组。它被称为带有属性的对象。大多数人是否都同意,最好不要混淆把JavaScript对象称为关联数组? - jfriend00
1
注意:如果你尝试在数组上使用“defineProperty”(如“Object.defineProperty.call(arr,'something','aught')”),它会抛出一个错误。 - David Hellsing
你说得对。键值“something”是对象的属性,而不是数组的索引 => arr.something。也许我太久没有睡觉了...我忘记了。谢谢。 @David - 很好,我不知道这个。 - abuduba
3
在控制台输入var a = []; a['test'] = ""; a;后显示为['test': ""],因此预期a.length为空。如果添加a[0] = 0;,则键'o'和'test'都具有'a'属性,这很奇怪! - Jean-Luc Barat

16

for( var i = arr.length; i--; console.log( arr[ i ] ) );

当然,这个代码只会给你数组的数字索引,但你仍然可以像这样循环遍历数组的数字索引字符串键:

for (var x in arr) {
    console.log(x + ": " + arr[x]);
}
/* (console output):
     0: 0
     1: 1
     2: 2
     3: 3
     something: aught
*/

1
所以,让我们添加这个 Array.prototype.somethingCool = "not really"; 然后运行你的 for-in-loop!! - KhaledMohamedP

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