JavaScript属性访问:点符号与方括号?


394

除了显而易见的事实,第一种形式可以使用变量而不仅仅是字符串文字,是否有理由在另一种形式上使用另一种形式?如果是这样,在哪种情况下?

在代码中:

// Given:
var foo = {'bar': 'baz'};

// Then
var x = foo['bar'];

// vs. 
var x = foo.bar;

上下文:我已经编写了一个代码生成器来生成这些表达式,我想知道哪种更好。


3
只是为了插手,而不是您最初的问题的答案(因为到目前为止您已经做了很多很好的解释),但是速度方面也没有什么值得一提:jsperf.com/dot-vs-square-brackets。上述测试最多只能给它们中的任何一个带来2%的余量,它们是并驾齐驱的。
不知情的2013年


此问题/答案也可以用于UTF-8键。
彼得·克劳斯

Answers:


422

(从此处获取。)

方括号表示法允许使用点符号不能使用的字符:

var foo = myForm.foo[]; // incorrect syntax
var foo = myForm["foo[]"]; // correct syntax

包括非ASCII(UTF-8)字符,如myForm["ダ"]更多示例)中所示。

其次,方括号表示法在处理以可预测的方式变化的属性名称时非常有用:

for (var i = 0; i < 10; i++) {
  someFunction(myForm["myControlNumber" + i]);
}

围捕:

  • 点符号的书写速度更快,阅读更清晰。
  • 方括号表示法允许访问包含特殊字符的属性以及使用变量选择属性

不能与点符号一起使用的字符的另一个示例是本身包含点的属性名称

例如,json响应可能包含一个名为的属性bar.Baz

var foo = myResponse.bar.Baz; // incorrect syntax
var foo = myResponse["bar.Baz"]; // correct syntax

45
摘要的代码示例和措辞看起来非常熟悉。dev-archive.net/articles/js-dot-notation
Quentin

61
不需要重新发明轮子吗?引用它作为参考。
Aron Rotteveel,2011年

13
点表示法更快(至少对我来说)测试您的浏览器jsperf.com/dot-notation-vs-bracket-notation/2
Dave Chen

4
在我的机器支架上用铬44表示会更快
奥斯汀法国

2
@chenghuayang当您想访问键存储在变量中的对象的属性时,不能使用点表示法。
阿卜杜勒

104

括号表示法允许您通过存储在变量中的名称访问属性:

var obj = { "abc" : "hello" };
var x = "abc";
var y = obj[x];
console.log(y); //output - hello

obj.x 在这种情况下将无法正常工作。


12

在JavaScript中访问属性的两种最常见的方法是使用点和方括号。两者都value.x and value[x]访问价值属性,但不一定是同一属性。区别在于x的解释方式。使用点时,点后的部分必须是有效的变量名,并且直接命名属性。使用方括号时,将对方括号之间的表达式求值以获取属性名称。value.x获取名为“ x”的值的属性,而value [x]尝试计算表达式x并将结果用作属性名称。

因此,如果您知道您感兴趣的属性称为“长度”,请说value.length。如果要提取由变量中保存的值命名的属性i,请说value[i]。并且由于属性名称可以是任何字符串,因此,如果要访问名为“2”或的属性“John Doe”,则必须使用方括号:value[2] or value["John Doe"]。即使您事先知道属性的确切名称,情况仍然如此,因为这两个都不“2” nor “John Doe”是有效的变量名称,因此无法通过点表示法进行访问。

如果是数组

数组中的元素存储在属性中。因为这些属性的名称是数字,并且我们经常需要从变量中获取它们的名称,所以我们必须使用方括号语法来访问它们。数组的length属性告诉我们它包含多少个元素。此属性名称是有效的变量名称,我们预先知道它的名称,因此通常要写成数组的长度,array.length因为它比容易写array["length"]


您能否详细说明array.length?您说不对通过点表示法访问的属性进行求值,所以在array.length的情况下,它不是为我们提供“ length”字符串而不是求值,在这种情况下,数组中的项目数是多少?The elements in an array are stored in properties这就是让我困惑的地方。您存储在属性中是什么意思?什么是属性?在我的理解中,数组只是一堆没有属性的值。如果它们存储在属性中,为什么它不是property: value/ associative数组?
Limpuls

这个答案特别有价值,因为它解释了两种表示法之间的区别。
象棋网'18

11

点表示法不适用于Internet Explorer 8中的某些关键字(例如newclass)。

我有以下代码:

//app.users is a hash
app.users.new = {
  // some code
}

这会触发可怕的“预期标识符”(至少在Windows XP的IE8上,我没有尝试过其他环境)。简单的解决方法是切换到括号符号:

app.users['new'] = {
  // some code
}

有用的答案。谢谢。
Ilyas karim


8

使用这些符号时要小心:例如。如果我们要访问窗口父级中存在的函数。在IE中:

window['parent']['func']

不等于

window.['parent.func']

我们可以使用:

window['parent']['func'] 

要么

window.parent.func 

访问它


6

一般来说,他们做同样的工作。
不过,方括号表示法让您有机会做点符号不能做的事情,例如

var x = elem["foo[]"]; // can't do elem.foo[];

可以将其扩展到任何包含特殊字符的属性。


5

如果属性名称具有特殊字符,则需要使用方括号:

var foo = {
    "Hello, world!": true,
}
foo["Hello, world!"] = false;

除此之外,我想这只是一个口味问题。恕我直言,点表示法更短,并且使它更明显地表明它是属性而不是数组元素(尽管JavaScript当然没有关联数组)。



3

在以下情况下,您必须使用方括号表示法:

  1. 属性名称是数字。

    var ob = {
      1: 'One',
      7 : 'Seven'
    }
    ob.7  // SyntaxError
    ob[7] // "Seven"
  2. 属性名称具有特殊字符。

    var ob = {
      'This is one': 1,
      'This is seven': 7,
    }  
    ob.'This is one'  // SyntaxError
    ob['This is one'] // 1
  3. 属性名称已分配给变量,并且您想通过此变量访问属性值。

    var ob = {
      'One': 1,
      'Seven': 7,
    }
    
    var _Seven = 'Seven';
    ob._Seven  // undefined
    ob[_Seven] // 7

1

情况[]记法是有帮助的:

如果您的对象是动态对象,并且键(例如number[]或任何其他特殊字符)中可能有一些随机值,例如-

var a = { 1 : 3 };

现在,如果您尝试像访问a.1错误那样访问,因为它在那儿期待一个字符串。


1

点符号始终是可取的。如果使用的是“更智能”的IDE或文本编辑器,它将显示该对象的未定义名称。仅当您的名称带有破折号或类似无效的名称时,才使用括号表示法。以及名称是否存储在变量中。


在某些情况下,即使您没有破折号,也根本不允许使用括号表示法。例如,您可以编写Math.sqrt(25),但不能编写Math['sqrt'](25)
李斯特先生

0

让我添加方括号表示法的更多用例。如果要访问x-proxy对象中的属性,-则将被错误地解释。它们还有其他一些情况,例如空格,点等,在这种情况下,点操作将无济于事。同样,如果u在变量中具有键,则访问括号中键值的唯一方法是使用括号表示法。希望您能获得更多背景信息。


0

点表示法失败的示例

json = { 
   "value:":4,
   'help"':2,
   "hello'":32,
   "data+":2,
   "😎":'😴',
   "a[]":[ 
      2,
      2
   ]
};

// correct
console.log(json['value:']);
console.log(json['help"']);
console.log(json["help\""]);
console.log(json['hello\'']);
console.log(json["hello'"]);
console.log(json["data+"]);
console.log(json["😎"]);
console.log(json["a[]"]);

// wrong
console.log(json.value:);
console.log(json.help");
console.log(json.hello');
console.log(json.data+);
console.log(json.😎);
console.log(json.a[]);

属性名称不应干扰javascript的语法规则,以便您能够以 json.property_name

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.