JavaScript属性访问:点符号和方括号哪个更好?

498

除了首个表单可以使用变量而不仅仅是字符串文字这一明显事实之外,是否有任何理由优先使用其中一种表单?如果有,在哪些情况下使用?

代码中:

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

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

// vs. 
var x = foo.bar;

背景:我编写了一个代码生成器,它输出这些表达式,我想知道哪个更好。


5
仅仅想插一句话,这并不是对你最初问题的回答(因为到目前为止你已经得到了足够好的解释),但就速度而言,它们之间没有值得一提的区别:http://jsperf.com/dot-vs-square-brackets。上面的测试结果最多只有2%的差距,它们几乎是不相上下的。 - unwitting
这个问题/答案也适用于UTF-8键。 - Peter Krauss
17个回答

505

(来源于这里。)

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

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

50
这些代码示例和摘要的措辞看起来非常眼熟。https://web.archive.org/web/20160304205521/http://www.dev-archive.net/articles/js-dot-notation/ - Quentin
69
重新发明轮子没有必要,对吧?可以将其引用为参考。 - Aron Rotteveel
14
点表示法更快(至少对我来说是这样),测试你的浏览器:http://jsperf.com/dot-notation-vs-bracket-notation/2 - Dave Chen
5
在我的计算机上,使用 Chrome 44 版本时,方括号表示法更快。 - Austin France
2
@chenghuayang 当你想要访问一个对象的属性,而这个属性的键是存储在一个变量中的时候,你就不能使用点符号来访问。 - Honinbo Shusaku
显示剩余13条评论

133

方括号表示法允许您使用存储在变量中的名称来访问属性:
var obj = { "abc" : "hello" };
var x = "abc";
var y = obj[x];
console.log(y); //output - hello

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


25
JavaScript中访问属性的两种最常用方法是使用点和方括号。 value.xvalue[x] 都访问value对象的属性,但不一定是同一个属性。区别在于如何解释x。 当使用点时,点后面的部分必须是有效的变量名,并直接命名为属性。当使用方括号时,方括号之间的表达式被评估以获取属性名称。因此,value.x获取命名为“x”的属性值,而value[x]尝试计算表达式x并将结果用作属性名称。
因此,如果您知道您感兴趣的属性名为"length",则可以使用value.length进行访问。如果要提取由变量持有的值命名的属性,则可以使用value[i]进行访问。由于属性名称可以是任何字符串,如果要访问名为"2""John Doe"的属性,则必须使用方括号: value[2]value["John Doe"]。即使您事先知道属性的确切名称,也要这样做,因为"2""John Doe" 都不是有效的变量名称,因此无法通过点表示法访问。
对于数组,数组中的元素存储在属性中。因为这些属性的名称是数字,我们经常需要从变量中获取它们的名称,因此必须使用方括号语法来访问它们。数组的length属性告诉我们它包含多少个元素。该属性名称是有效的变量名称,我们事先知道其名称,因此要找到数组的长度,通常会编写array.length,因为这比编写array["length"]更容易。

你能详细解释一下array.length吗?你说通过点符号访问的属性不会被计算,那么在array.length的情况下,它不会给我们返回"length"字符串而不是数组中项数的计算值吗?“数组中的元素存储在属性中”,这就让我感到困惑了。你所说的属性是什么意思?在我看来,数组只是一堆没有属性的值。如果它们存储在属性中,那么它为什么不是“属性:值”/关联数组呢? - Limpuls
2
这个答案特别有价值,因为它解释了这两种符号之间的区别。 - chessweb

15

在Internet Explorer 8中,点符号表示法无法与一些关键字(例如newclass)一起使用。

我有这段代码:

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

这会触发令人恐惧的“预期标识符”错误(至少在Windows XP上的IE8中会出现此问题,我尚未尝试其他环境)。解决此问题的简单方法是切换到方括号表示法:

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

1
有用的答案。谢谢。 - Ilyas karim
1
适用于Chrome 2019年 https://res.cloudinary.com/rootworld/image/upload/v1567651133/js.png - Phani Rithvij

13

foo.barfoo["bar"]都可以访问 foo 对象的某个属性,但不一定是同一个属性。区别在于如何解释 bar。使用点时,点后面的单词是属性的字面名称。使用方括号时,方括号内的表达式将被计算以获取属性名称。foo.bar获取名为"bar"的属性值,而foo["bar"]尝试计算表达式 "bar" 并使用结果(转换为字符串)作为属性名称。

点表示法的局限性

如果我们有这个对象:

const obj = {
  123: 'digit',
  123name: 'start with digit',
  name123: 'does not start with digit',
  $name: '$ sign',
  name-123: 'hyphen',
  NAME: 'upper case',
  name: 'lower case'
};

使用点表示法访问他们的属性

obj.123;      // ❌ SyntaxError
obj.123name;  // ❌ SyntaxError
obj.name123;  // ✅ 'does not start with digit'
obj.$name;    // ✅  '$ sign'
obj.name-123;  // ❌ SyntaxError
obj.'name-123';// ❌ SyntaxError
obj.NAME; // ✅ 'upper case'
obj.name; // ✅ 'lower case'

但对于方括号表示法来说,这些都不是问题:

obj['123'];     // ✅ 'digit'
obj['123name']; // ✅ 'start with digit'
obj['name123']; // ✅ 'does not start with digit'
obj['$name'];   // ✅ '$ sign'
obj['name-123']; // ✅ 'does not start with digit'
obj['NAME']; // ✅ 'upper case'
obj['name']; // ✅ 'lower case'

使用变量访问变量:

const variable = 'name';
const obj = {
  name: 'value'
};
// Bracket Notation
obj[variable]; // ✅ 'value'
// Dot Notation
obj.variable; // undefined

由于评估,使用括号表示法会更慢吗? - neoexpert

11

一般来说,它们完成相同的工作。
然而,括号表示法给了你一些用点表示法无法实现的机会,比如

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

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

10

如果属性名包含特殊字符,则需要使用括号:

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

除此之外,我想这只是个人口味问题。在我看来,点表示法更短,并且它使属性与数组元素更加明显(尽管当然 JavaScript 无法使用关联数组)。


9

当您使用中括号表示法时 -

  1. The property name is number.

    var ob = {
      1: 'One',
      7 : 'Seven'
    }
    ob.7  // SyntaxError
    ob[7] // "Seven"
    
  2. The property name has special character.

    var ob = {
      'This is one': 1,
      'This is seven': 7,
    }  
    ob.'This is one'  // SyntaxError
    ob['This is one'] // 1
    
  3. The property name is assigned to a variable and you want to access the property value by this variable.

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

9

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

window['parent']['func']

不等于

window.['parent.func']

我们可以使用以下方式之一:
window['parent']['func'] 

或者
window.parent.func 

访问它


5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接