JavaScript 数组的索引是数组。

7

我不理解下面这段代码的Javascript解释:

var a = ["value"];
console.log(a[0]); // value
console.log(a[[0]]); // value
console.log(a[[[0]]]); // value
//...

为什么数组的值被视为0?


6
[0].toString() 将返回 "0"。a["0"] === "value" 表示对象 a 中键名为字符串 "0" 的键对应的值为字符串 "value"。 - user120242
@user120242 那么隐式的 .toString() 的解释是什么? - Andreas
a[~~![]] === a[+[]] - Endless
我不是 ECMA-Script 的开发者,但我想说他们内置了一个忽略不必要维度的功能。在你的情况下,很明显两个外部括号没有必要也没有用处,因此 JavaScript 仍然只执行 "console.log(a[0])"。这只是一个观点。 - user6749601
1
数组是具有特殊处理数组索引的异类对象。如果输入属性不是数组索引(可表示整数),并且由于数组仍然是对象,它会级联到正常的对象访问,随后在隐式转换为字符串以适合可以是字符串或符号的属性名称后,级联回整数/数组索引访问。在ECMA-262规范中有大量相关规范。我不知道这是否值得尝试完全编写? - user120242
显示剩余2条评论
1个回答

2
方括号表示法用作属性访问器,在ECMAScript语言规范的“属性访问器”章节中有定义。方括号之间的表达式在第4步中被处理为:

EvaluatePropertyAccessWithExpressionKey(baseValue,Expression,strict)。

这反过来执行以下步骤:

ToPropertyKey(propertyNameValue)。

... 反过来执行此步骤:

ToPrimitive(argument,hint String)。

如果您在规范中进一步查看,将转换该表达式为字符串(如果它是对象),并使用Symbol.toPrimitive(如果已定义)或toString方法。是的,如果最外层括号之间的表达式是数组(可能嵌套),例如[0]、[[0]]等,则传递一个对象。
一个数组通过其 toString() 方法转换为字符串后,将产生逗号分隔的值的字符串。这递归地作用于嵌套数组,因此实际上意味着所有值,无论多么深度嵌套,都会在结果逗号分隔的字符串中显示出来。例如,[[1, 2], 3, [4, [5]]].toString() 的结果是 "1,2,3,4,5"。
在您的示例中,您传递给外部括号对的表达式中始终只有一个值,即0。因此,这个表达式(如 [[[[[0]]]]].toString())解析为 "0"。
因此,我们得到了 a["0"],它与 a[0] 是相同的。

为什么 a["0"] === a[0]?在尝试访问属性时,它是否将“0”转换为0? - zb22
1
请查看@zb22 https://tc39.es/ecma262/#sec-integerindexedelementget,了解整数索引和数组索引的定义以及“CanonicalNumericIndexString”。 - user120242
@zb22 https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-get-p-receiver 贴错了哈希值,这是你想要查看的正确哈希值。 - user120242

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