我正在为资源极其有限的嵌入式设备(http://www.espruino.com)编写一个JavaScript解释器,每次我认为我正确地实现了一些JavaScript时,我就意识到我错了。
我现在的问题是关于[]
的。如何正确实现JavaScript的最基本部分之一?
我已经看过了JavaScript规范,也许我没有找到合适的部分,但我找不到有用的答案。
我之前假设你实际上有两个“映射”--一个用于整数,另一个用于字符串。数组长度是最高整数的值加1。然而,根据chrome上的jsconsole,这似乎是错误的:
var a = [];
a[5] = 42;
a["5"]; // 42
a.length; // 6
但也包括:
var a = [];
a["5"] = 42;
a[5]; // 42
a.length; // 6
所以..。太棒了-一切都被转换成字符串,并使用表示整数的最高值字符串(加1)来获得长度?不对。
var a = [];
a["05"] = 42;
a.length; // 0
"05"
是一个有效的整数-即使是八进制。那么为什么它不会影响长度呢?
是否必须将字符串转换为整数,然后检查转换回字符串时是否匹配?
有没有人参考过用来存储和获取数组或对象中的项的确切算法?看起来应该很简单,但实际上并非如此!
发布于 2013-04-11 19:56:25
正如说明书所说,并被其他人注意到:
“当且仅当ToString( ToUint32(P) )等于P且ToUint32(P)不等于2^32-1时,属性名P(以字符串值的形式)是数组索引。”
这就解释了为什么在您场景中,"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
注意:在JS中,Zero-fill right shift是替代ToUint32
的最短方式,将一个数字移零。
发布于 2013-04-11 19:28:20
请参阅MDN
也可以引用JavaScript数组索引(例如,年份“2”而不是years2),尽管这不是必需的。无论如何,years2中的2最终都会被JavaScript引擎通过隐式toString转换强制转换为字符串。正是由于这个原因,"2“和"02”将引用years对象上的两个不同的槽,并且下面的示例记录为真:
console.log(years["2"] != years["02"]);
因此,使用a["5"]
访问数组,而a["05"]
在数组对象上设置一个属性。
发布于 2013-04-11 19:27:37
数组就是对象。这意味着它们可以具有不被视为数组元素的附加属性。
如果方括号参数是整数,它将使用该参数对数组执行赋值。否则,它将其视为字符串,并将其存储为数组对象上的属性。
DCoder基于delnan的注释和的注释,这是JavaScript确定它是否为数组的合适索引(而不仅仅是属性)的方式: http://www.ecma-international.org/ecma-262/5.1/#sec-15.4
https://stackoverflow.com/questions/15957085
复制相似问题