JavaScript属性访问:点符号vs.括号?

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

在代码:

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


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


// vs.
var x = foo.bar;

上下文:我写了一个代码生成器,产生这些表达式,我想知道哪个更可取。

188097 次浏览

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

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

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

(来自在这里。)

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

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

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

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

在这种情况下obj.x将不起作用。

一般来说,他们做同样的工作 尽管如此,括号表示法让您有机会做点表示法不能做的事情,比如

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

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

在ie8中,点表示法不适用于某些关键字(如newclass)。

我有这样的代码:

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

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

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

括号表示法可以使用变量,所以它在两个点表示法不起作用的情况下很有用:

1)动态确定属性名时(直到运行时才知道确切的名称)。

2)当使用for..in循环遍历对象的所有属性时。

来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects

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

window['parent']['func']

并不等同于

window.['parent.func']

我们可以用:

window['parent']['func']

window.parent.func

访问它

[]符号有用的情况:

如果你的对象是动态的,并且在键中可能有一些随机值,如number和__abc1或任何其他特殊字符,例如-

var a = { 1 : 3 };

现在,如果你试图像a.1那样访问,它会报错,因为它期望在那里有一个字符串。

让我再添加一些方括号符号的用例。如果你想访问一个对象中的属性,比如x-proxy,那么-将被错误地解释。还有一些其他的情况,比如空格,点,等等,点运算对你没有帮助。另外,如果你在一个变量中有键,那么在一个对象中访问键值的唯一方法是用括号符号。希望你能了解更多的背景。

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

因此,如果你知道你感兴趣的属性是“length”,你可以说value.length。如果你想提取由变量i中包含的值命名的属性,你可以说value[i]。因为属性名可以是任何字符串,如果你想访问名为“2”“John Doe”的属性,你必须使用方括号:value[2]value["John Doe"]。即使你事先知道属性的确切名称,情况也是如此,因为“2”“John Doe”都不是有效的变量名,因此不能通过点表示法访问。

在数组的情况下

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

当-时必须使用方括号

  1. 属性名为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
    

点表示法失败的例子

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访问它们

点表示法总是可取的。如果你正在使用一些“更聪明的”IDE或文本编辑器,它将显示来自该对象的未定义名称。 只有当你的名字有破折号或类似无效的东西时,才使用括号符号。如果名称存储在一个变量中。

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'

使用variable访问变量:

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

或者当你想动态改变一个元素的classList动作时:

// Correct


showModal.forEach(node => {
node.addEventListener(
'click',
() => {
changeClass(findHidden, 'remove'); // Correct
},
true
);
});


//correct
function changeClass(findHidden, className) {
for (let item of findHidden) {
console.log(item.classList[className]('hidden'));// Correct
}
}


// Incorrect
function changeClass(findHidden, className) {
for (let item of findHidden) {
console.log(item.classList.className('hidden')); // Doesn't work
}
}

我举了另一个例子来清楚地理解用法上的差异。当使用嵌套数组和嵌套对象时

    const myArray = [
{
type: "flowers",
list: [ "a", "b", "c" ],
},
{
type: "trees",
list: [ "x", "y", "z" ],
}
];

现在,如果我们想访问树列表means y中的第二项。

我们不能一直用括号

const secondTree = myArray[1]["list"][1]; // incorrect syntex

相反,我们必须使用

const secondTree = myArray[1].list[1]; // correct syntex

点表示法和括号表示法都用于在JavaScript中访问对象属性。点表示法是最常用的,因为它更容易阅读和理解。为什么我们要用括号,这两者有什么区别呢?括号符号[]允许我们使用变量访问对象属性,因为它将方括号内的表达式转换为字符串。

const person = {
name: 'John',
age: 30
};


//dot notation
const nameDot = person.name;
console.log(nameDot);
// 'John'


const nameBracket = person['name'];
console.log(nameBracket);
// 'John'

现在,让我们看一个变量的例子:

const person = {
name: 'John',
age: 30
};


const myName = 'name';
console.log(person[myName]);
// 'John'

点表示法的另一个优点是只包含字母数字(以及_和$),例如,如果你想访问一个像下面这样的对象(包含'-',你必须使用括号表示法)

const person = {
'my-name' : 'John'
}


console.log(person['my-name']); // 'John'
// console.log(person.my-name); // Error