属性 个有效名称,属性 个分配和访问 JavaScript
Valid property names, property assignment and access in JavaScript
更新问题
在 Javascript 中,什么是有效的 属性 名称? 属性 赋值的各种方法有何不同? 属性 名称如何影响 属性 访问?
备注
我最初问题的答案(见下文)有助于澄清一些问题,但也打开了一个新的蠕虫罐头。现在我有机会更加熟悉 JavaScript,我 相信 我已经能够想出很多东西了。
因为我很难找到将这些信息整合成一个解释,所以我认为扩展我原来的问题并尝试回答它可能会有所帮助。
原问题
最初,MDN JavaScript guide (object literals) 有一些混淆。具体来说,我想知道为什么他们声称如果 属性 名称不是有效的 JavaScript 标识符,那么它必须用引号引起来。然而,他们提供了示例代码,显示数字 7 可以用作 - 不带引号 - 作为 属性 名称。
事实证明,指南只是遗漏了一个重要部分,Pointy 对其进行了更新(更改以粗体显示):
If the property name would not be a valid JavaScript identifier or number, it must be enclosed in quotes.
我还想知道为什么允许 属性 名称偏离适用于标识符的 "may not start with a digit" 规则。这个问题实际上揭示了我对 属性 名字的完全误解,这促使我做更多的研究。
简答
对象 属性 名称可以是任何 valid identifier, numeric literal, or string literal(包括空字符串)。
话虽如此,关于 JavaScript 属性 名称,需要牢记一些可能令人困惑的错综复杂之处,如下所述。
除非您使用有效(非负整数)数组索引,否则最好将所有数字 属性 名称显式分配为字符串。
负数
看起来像负数的东西实际上是一个表达式 — 属性 名称不支持。
// SyntaxError
const obj = { -12: 'nope' };
幸运的是,括号表示法为我们处理表达式。
// Successful property assignment.
const obj = {};
obj[-12] = 'yup';
类型转换
所有 属性 名称在存储之前都被转换为字符串。
const obj = {
12: '12'
};
console.log(typeof Object.keys(obj)[0]); // -> string
正在解析
但即使在进行类型转换之前,键也会根据使用的语法进行解析,并转换为十进制文字。
const obj = {
// Valid string literal
'022': '022',
// Interpreted as decimal
6: '6',
// Interpreted as floating-point
.345: '0.345',
// Interpreted as floating-point
1.000: '1',
// Interpreted as floating-point
8.9890: '8.989',
// Interpreted as decimal
000888: '888',
// Interpreted as octal
0777: '511',
// Interpreted as hexadecimal
0x00111: '273',
// Interpreted as binary
0b0011: '3',
};
/* Quoted property name */
console.log(obj['022']); // "022"; as expected
console.log(obj[022]); // undefined; 022 is an octal literal that evaluates to 18 before our lookup ever occurs
/* Valid (non-negative integer) array index */
console.log(obj[6]); // "6"; as expected
console.log(obj['6']); // "6"; as expected
/* Non-valid array index */
console.log(obj[0x00111]); // "273"; we're accessing the property name as it was assigned (before it was parsed and typecasted)
console.log(obj['0x00111']); // undefined; after parsing and typecasting, our property name seems to have disappeared
console.log(obj['273']); // "273"; there it is, we found it using the evaluation of our original assignment
第一个问题的答案:
是的,MDN 指南中给出的声明并非 100% 准确,但在您的日常工作中最好遵循它作为规则。您真的不需要创建数字属性名称。
第二个问题的答案:
A property name may not start with a digit but a property name that is a number without any other characters in its name is fine.
存在此异常是因为名称编号与indexes
相同的属性。
让我们试试这个:
var obj = {7: "abc"};
obj[7]; // works fine
obj.7; // gives an error (SyntaxError)
现在尝试对对象调用 Array.push
并观察会发生什么:
Array.prototype.push.call(obj, "xyz");
console.log(obj);
console.log(obj[0]);
// Prints
Object {0: "xyz", 7: "abc", length: 1}
"xyz"
您可以看到几乎没有新属性(一个名称为 0
,另一个名称为 length
)已添加到对象中。此外,您可以将对象用作数组:
var obj = { "0": "abc", "1": "xyz", length: 2 };
Array.prototype.pop.call(obj); // Returns: "xyz"
Array.prototype.pop.call(obj); // Returns: "abc"
您可以在对象上使用数组的方法,这称为 Duck Typing
。
数组只不过是具有一些预定义方法的对象。
来自MDN:
Array elements are object properties in the same way that length is a property, but trying to access an element of an array with dot notation throws a syntax error, because the property name is not valid. There is nothing special about JavaScript arrays and the properties that cause this. JavaScript properties that begin with a digit cannot be referenced with dot notation and must be accessed using bracket notation.
现在您可以理解为什么 属性 名称的数字是有效的了。这些被称为索引,它们用于 JavaScript 数组。由于 JavaScript 需要与其他语言保持一致,因此数字对 indexes/properties 名称有效。
希望这能说明问题。
这里有一些有趣的文章:
更新问题
在 Javascript 中,什么是有效的 属性 名称? 属性 赋值的各种方法有何不同? 属性 名称如何影响 属性 访问?
备注
我最初问题的答案(见下文)有助于澄清一些问题,但也打开了一个新的蠕虫罐头。现在我有机会更加熟悉 JavaScript,我 相信 我已经能够想出很多东西了。
因为我很难找到将这些信息整合成一个解释,所以我认为扩展我原来的问题并尝试回答它可能会有所帮助。
原问题
最初,MDN JavaScript guide (object literals) 有一些混淆。具体来说,我想知道为什么他们声称如果 属性 名称不是有效的 JavaScript 标识符,那么它必须用引号引起来。然而,他们提供了示例代码,显示数字 7 可以用作 - 不带引号 - 作为 属性 名称。
事实证明,指南只是遗漏了一个重要部分,Pointy 对其进行了更新(更改以粗体显示):
If the property name would not be a valid JavaScript identifier or number, it must be enclosed in quotes.
我还想知道为什么允许 属性 名称偏离适用于标识符的 "may not start with a digit" 规则。这个问题实际上揭示了我对 属性 名字的完全误解,这促使我做更多的研究。
简答
对象 属性 名称可以是任何 valid identifier, numeric literal, or string literal(包括空字符串)。
话虽如此,关于 JavaScript 属性 名称,需要牢记一些可能令人困惑的错综复杂之处,如下所述。
除非您使用有效(非负整数)数组索引,否则最好将所有数字 属性 名称显式分配为字符串。
负数
看起来像负数的东西实际上是一个表达式 — 属性 名称不支持。
// SyntaxError
const obj = { -12: 'nope' };
幸运的是,括号表示法为我们处理表达式。
// Successful property assignment.
const obj = {};
obj[-12] = 'yup';
类型转换
所有 属性 名称在存储之前都被转换为字符串。
const obj = {
12: '12'
};
console.log(typeof Object.keys(obj)[0]); // -> string
正在解析
但即使在进行类型转换之前,键也会根据使用的语法进行解析,并转换为十进制文字。
const obj = {
// Valid string literal
'022': '022',
// Interpreted as decimal
6: '6',
// Interpreted as floating-point
.345: '0.345',
// Interpreted as floating-point
1.000: '1',
// Interpreted as floating-point
8.9890: '8.989',
// Interpreted as decimal
000888: '888',
// Interpreted as octal
0777: '511',
// Interpreted as hexadecimal
0x00111: '273',
// Interpreted as binary
0b0011: '3',
};
/* Quoted property name */
console.log(obj['022']); // "022"; as expected
console.log(obj[022]); // undefined; 022 is an octal literal that evaluates to 18 before our lookup ever occurs
/* Valid (non-negative integer) array index */
console.log(obj[6]); // "6"; as expected
console.log(obj['6']); // "6"; as expected
/* Non-valid array index */
console.log(obj[0x00111]); // "273"; we're accessing the property name as it was assigned (before it was parsed and typecasted)
console.log(obj['0x00111']); // undefined; after parsing and typecasting, our property name seems to have disappeared
console.log(obj['273']); // "273"; there it is, we found it using the evaluation of our original assignment
第一个问题的答案:
是的,MDN 指南中给出的声明并非 100% 准确,但在您的日常工作中最好遵循它作为规则。您真的不需要创建数字属性名称。
第二个问题的答案:
A property name may not start with a digit but a property name that is a number without any other characters in its name is fine.
存在此异常是因为名称编号与indexes
相同的属性。
让我们试试这个:
var obj = {7: "abc"};
obj[7]; // works fine
obj.7; // gives an error (SyntaxError)
现在尝试对对象调用 Array.push
并观察会发生什么:
Array.prototype.push.call(obj, "xyz");
console.log(obj);
console.log(obj[0]);
// Prints
Object {0: "xyz", 7: "abc", length: 1}
"xyz"
您可以看到几乎没有新属性(一个名称为 0
,另一个名称为 length
)已添加到对象中。此外,您可以将对象用作数组:
var obj = { "0": "abc", "1": "xyz", length: 2 };
Array.prototype.pop.call(obj); // Returns: "xyz"
Array.prototype.pop.call(obj); // Returns: "abc"
您可以在对象上使用数组的方法,这称为 Duck Typing
。
数组只不过是具有一些预定义方法的对象。
来自MDN:
Array elements are object properties in the same way that length is a property, but trying to access an element of an array with dot notation throws a syntax error, because the property name is not valid. There is nothing special about JavaScript arrays and the properties that cause this. JavaScript properties that begin with a digit cannot be referenced with dot notation and must be accessed using bracket notation.
现在您可以理解为什么 属性 名称的数字是有效的了。这些被称为索引,它们用于 JavaScript 数组。由于 JavaScript 需要与其他语言保持一致,因此数字对 indexes/properties 名称有效。
希望这能说明问题。
这里有一些有趣的文章: