Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript[]到底是如何工作的?_Javascript_Arrays_Dictionary_Associative Array - Fatal编程技术网

JavaScript[]到底是如何工作的?

JavaScript[]到底是如何工作的?,javascript,arrays,dictionary,associative-array,Javascript,Arrays,Dictionary,Associative Array,我正在为资源极其有限的嵌入式设备()编写一个JavaScript解释器,每次我认为我已经正确地实现了一些JavaScript,我就意识到我错了 我现在的问题是关于[]。如何正确实现JavaScript最基本的部分之一 我浏览了JavaScript规范,可能还没有找到正确的部分,但我找不到有用的答案 我之前假设您实际上有两个“映射”——一个用于整数,一个用于字符串。数组长度是最大整数加1的值。然而,根据chrome上的jsconsole,这似乎是错误的: var a = []; a[5] = 42

我正在为资源极其有限的嵌入式设备()编写一个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”
是有效的整数-即使是八进制。那么为什么它不影响长度呢

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


是否有人引用过用于在数组或对象中存储和获取项的精确算法?看起来它应该很简单,但看起来它实际上不是

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

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

编辑基于delnan的注释和DCoder的注释,这是JavaScript如何确定它是否是数组的适当索引(而不仅仅是属性):

请参见

也可以引用JavaScript数组索引(例如。, 年[“2”]而不是年[2]),尽管这不是必需的。2英寸 年[2]最终被JavaScript强制转换成字符串 引擎,无论如何,通过隐式的toString转换。这是给你的 这就是为什么“2”和“02”指的是网络上的两个不同插槽的原因 years对象和以下示例记录为true:


因此,使用
a[“5”]
可以访问数组,而
a[“05”]
可以设置数组对象的属性。

数组也是对象

通过这样做

a["05"] = 5;
您正在做的事情与:

a.05 = 5;
但是上述操作将导致语法错误,因为点后指定的属性不能以数字开头

因此,如果您这样做:

a = [];
a["05"] = 5;
您仍然有一个空数组,但是名为
05
a
的属性的值为
5


编号
x
当且仅当
ToString(ToUint32(x))
等于
x
(因此在
“05”
的情况下,不满足该要求)。

如规范所述,其他人注意到:

“当且仅当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中,最短的方法是用
ToUint32
替换,将数字移位为零。

最后一部分不是特别有用,除非您准确定义了什么是“整数”,什么不是。例如,“05”是整数吗?为什么?说明:“属性名
P
(以
字符串的形式
值)是数组索引,当且仅当
ToString(ToUint32(P))
等于
P
ToUint32(P)
不等于
2**32-1
。如果您正在编写解释器,则不应使用假设。您应该阅读规范。为什么不使用现有的、功能强大且符合标准的JS实现,比如V8?我当时读到的内容听起来很可怕:-/@Bergi V8和其他所有JIT编译器一样,很难移植,不适合资源受限的设备。不仅JIT编译器的输出架构是特定的,为代码设置内存也是特定于操作系统的。JIT编译器实际上总是比简单的解释器使用更多的内存。他们还需要一些时间来热身和变快。所有这些都使它们非常不适合于资源很少的晦涩设备。谢谢-事实上,我在发布之前确实在规范中找到了这一点,但我一定是找错了地方。谢谢-这也解释了数组长度的问题,其他答案并没有真正解决这个问题。感谢您提供规范以及DCoder的链接
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