JavaScript []如何真正起作用?

时间:2013-04-11 19:22:19

标签: javascript arrays dictionary associative-array

我正在为极其资源受限的嵌入式设备(http://www.espruino.com)编写一个JavaScript解释器,每当我认为我已经正确实现了一些JavaScript时,我就意识到我错了。

我现在的问题是关于[]。您如何正确实现JavaScript最基本的部分之一?

我查看了JavaScript规范,也许我找不到正确的位,但我找不到有用的答案。

我之前曾假设您实际上有两个'地图' - 一个用于整数,一个用于字符串。并且数组长度是最高整数加1的值。然而,这似乎是错误的,根据铬的jsconsole:

var a = [];
a[5] = 42;
a["5"]; // 42
a.length; // 6

但也是:

var a = [];
a["5"] = 42;
a[5]; // 42
a.length; // 6

所以......很棒 - 一切都被转换成一个字符串,并且使用表示整数的最高值字符串(加一)来获取长度?错。

var a = [];
a["05"] = 42;
a.length; // 0

"05"是一个有效的整数 - 即使在八进制中也是如此。那为什么它不影响长度?

你是否必须将字符串转换为整数,然后在转换回字符串时检查它是否匹配?

有没有人引用用于存储和获取数组或对象中项目的确切算法?它看起来应该很简单,但看起来它实际上并非如此!

4 个答案:

答案 0 :(得分:4)

请参阅MDN

  

也可以引用JavaScript数组索引(例如,   年[[2“]而不是年[2]),虽然没有必要。 2英寸   年[2]最终被JavaScript强制转换为字符串   无论如何,通过隐式toString转换引擎。那是为了   这个原因,“2”和“02”指的是两个不同的插槽   years对象和以下示例记录为true:

console.log(years["2"] != years["02"]);

因此,使用a["5"]访问数组时,a["05"]会在数组对象上设置属性。

答案 1 :(得分:4)

正如规范所说,并被其他人注意到:

  

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

这就解释了为什么在您的方案中"5"被视为数组索引而"05"不是:

console.log("5" === String("5" >>> 0));
// true, "5" is equal to "5", so it's an index

console.log("05" === String("05" >>> 0));
// false, "05" is not equal to "5", so it's not an index

注意:Zero-fill right shift是JS中替换ToUint32的最短路径,将数字移动为零。

答案 2 :(得分:3)

数组只是对象。这意味着它们可以具有不被视为数组元素的其他属性。

如果方括号参数是整数,则使用它来执行对数组的赋值。否则,它将其视为字符串并将其作为属性存储在数组对象上。

根据delnan的评论和DCoder的评论进行编辑,这就是JavaScript如何确定它是否是数组的适当索引(而不仅仅是属性): http://www.ecma-international.org/ecma-262/5.1/#sec-15.4

答案 3 :(得分:1)

数组也是对象。

通过这样做

a["05"] = 5;

你正在做同样的事情:

a.05 = 5;

但是,以上操作会导致语法错误,因为在点无法以数字开头后指定的属性。

所以,如果你这样做:

a = [];
a["05"] = 5;

您仍然有空数组,但名为a的{​​{1}}的属性值为05

数字5 is an array index当且仅当x等于ToString(ToUint32(x))时(如果x不符合要求,则为<}}。< / p>