使用括号访问JavaScript属性

使用括号访问JavaScript属性,javascript,Javascript,如果我在Chrome控制台中声明以下内容: var object = {0:0, 1:1} 我可以调用对象[0]和对象[1]并获取它们的值。我还可以调用对象[“0”]和对象[“1”]。接下来,如果我声明: var object = {"0":0, "1":1} var object = {a:0, 1:1} 我也可以打上述四个电话。但如果我宣布: var object = {"0":0, "1":1} var object = {a:0, 1:1} 当我调用对象[a]时,我得到一个Re

如果我在Chrome控制台中声明以下内容:

var object = {0:0, 1:1}
我可以调用对象[0]和对象[1]并获取它们的值。我还可以调用对象[“0”]和对象[“1”]。接下来,如果我声明:

var object = {"0":0, "1":1}
var object = {a:0, 1:1}
我也可以打上述四个电话。但如果我宣布:

var object = {"0":0, "1":1}
var object = {a:0, 1:1}

当我调用对象[a]时,我得到一个ReferenceError“a未定义”,但对象[“a”]返回0,即使声明中的属性名不是字符串。我猜JavaScript认为我在调用第一个示例中不存在的变量。但是为什么调用对象[0]和对象[“0”]都能工作呢?JavaScript似乎正在对数字进行某种自动转换(可能是因为它们不能是变量名),但这方面的规则是什么?这种行为在其他地方是普遍存在的,还是只适用于对象的括号符号?

对于
object[a]
,出现
ReferenceError
的原因是,文本
a
在javascript中是一个变量<代码>“a”是包含字母a的字符串

您可以使用点表示法
object.a
或括号表示法与
object[“a”]

也可以使用变量进行访问

var x = "a";
object[x];   //=> 0

var y = 1;
object[y];   //=> 1

使用括号时,将计算括号内的表达式。表达式的值是多少

 a
???好吧,如果“a”不是一个声明的变量,那就是胡说八道。使用
表示法时,运算符后面的标识符(它必须是标识符)将被视为字符串。这就是语言的工作方式。

你是对的

a
有一个令牌,引擎假定它是一个变量

如果键入
“a”
JS知道它是字符串原语。
如果键入
0
,JS知道这是一个数字原语

因此,在
obj.a
obj[“a”]
obj[0]
obj[“0”]
之上,您还可以说:

var a = 0;
obj[a]; // 0
你的应用程序正在爆炸,因为
a
尚未定义,现在你想使用它

是的,这是预期的行为。
括号内的内容不被视为对象的“一部分”——这是一种表示“给我这个键引用的对象的值”的方式,其中键可能是数字或字符串(或可以强制转换为字符串或数字的东西)

将来,使用贴图和weakmap,您实际上也可以使用其他对象/函数作为键

var obj  = new Map(),
    func = function () { },
    el   = document.getElementById("myId");

obj[func] = 1;
obj[el]   = 2;
现在,这些东西在技术上起作用。。。但这只是因为它们被转换为字符串值。。。因此,如果您有两个编写相同的函数(但从技术上讲是两个不同的对象),那么您将覆盖当前的值。
在地图内部,它们将被视为单独的对象

现在使用DOM元素更糟糕,因为存储数百个DOM元素并将引用绑定到它们可能会很有用,这样您就不必一直寻找它们。。。但现在,您需要为每一个创建一个唯一的ID号/密钥,并存储该ID号/密钥,记住密钥,然后创建一个子对象来保存所需的数据

而在未来,有了地图,你可以说:

var my_els = document.querySelector(".lots-of-els");

for (let el of my_els /* also the future */) {
    console.log( my_map_of_data[el].info );
}

我想,我的问题是,当我声明的属性名为a而不是“a”时,为什么object[“a”]起作用。如果JavaScript自动将我的声明从{a:0}转换为{“a”:0},为什么对象[0]和对象[“0”]都可以工作,但对象[a]不能工作?根据这种逻辑,如果我将对象声明为{“0”:0,“1”:1},obj[0]不应该工作,因为它返回的是0,而不是“0”?但是这个电话确实起作用了……不,那是不对的,@ZackGao。属性名称始终被解释为字符串。即使对于实际阵列也是如此!同样,这是语言的定义方式。