究竟什么是Javascript中有效的属性名称?各种财产分配方法有何不同?属性名称如何影响属性访问?
我原来的问题(见下文)的答案有助于澄清一些事情,但也开启了一堆新的蠕虫。现在我已经有机会对JavaScript变得更熟悉了,我相信我已经能够解决很多问题。
由于我很难将这些信息整合到一个解释中,我认为扩展原始问题可能会有所帮助,并试图回答它。
最初,与MDN JavaScript guide (object literals)存在一些混淆。具体来说,我想知道为什么他们声称如果属性名称不是有效的JavaScript标识符,那么它必须用引号括起来。然而,他们提供了示例代码,表明可以使用数字7 - 没有引号 - 作为属性名称。
事实证明,该指南只是遗漏了一个重要部分,Pointy更新了它(粗体更改):
如果属性名称不是有效的JavaScript标识符或数字,则必须将其括在引号中。
我也想知道为什么允许属性名称偏离"可能不会以数字开头#34;规则,适用于标识符。这个问题实际上揭示了我对属性名称的完全误解,并且是导致我做更多研究的原因。
答案 0 :(得分:2)
回答第一个问题:
是的,MDN指南中的陈述并非100%准确,但在日常工作中,最好遵守规则。您真的不需要创建数字属性名称。
回答第二个问题:
属性名称不能以数字开头,但属性名称可以是名称中没有任何其他字符的数字。
此异常的存在是因为名称编号的属性与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:
数组元素是对象属性,其方式与length属性相同,但尝试使用点表示法访问数组元素会引发语法错误,因为属性名称无效。 JavaScript数组和导致此问题的属性没有什么特别之处。以数字开头的JavaScript属性不能用点表示法引用,必须使用括号表示法访问。
现在您可以理解为什么属性名称的数字有效。这些只是索引,它们用在JavaScript数组中。由于JavaScript需要与其他语言保持一致,因此数字对索引/属性名称有效。
希望这说清楚。
以下是一些有趣的文章:
答案 1 :(得分:1)
对象属性名称可以是任意valid identifier,numeric literal或string literal(包括空字符串)。
话虽如此,但有一些可能令人困惑的错综复杂要记住JavaScript属性名称(摘要如下,explored more on my own)。
看起来像负数的实际上是一个表达式 - 属性名称不支持。
$(function () {
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() == 0) {
console.log("USER SCROLLED TO TOP");
mixpanel.track(
"User Scrolled To Top", {
"url": window.location.href
});
} else if ($win.height() + $win.scrollTop() >= $('#below-fold').height() - 0 && $win.height() + $win.scrollTop() <= $('#below-fold').height() + 0) {
console.log("VIEWED BELOW THE FOLD");
mixpanel.track(
"User Scrolled Below Fold", {
"url": window.location.href
});
} else if ($win.height() + $win.scrollTop() == $(document).height()) {
console.log("USER SCROLLED TO BOTTOM");
mixpanel.track(
"User Scrolled To Bottom", {
"url": window.location.href
});
}
});
});
幸运的是,括号表示法为我们处理表达式。
var obj = {
-12: 'nope' // I am an invalid property name, because I am an expression.
};
在存储之前,所有属性名称都被转换为字符串。
obj[-6] = 'yup'; // Successful property assignment. We're good here.
但即使在此之前,它们也会根据使用的语法进行解析,并转换为十进制文字。
var obj = {
lego: 'Everything is cool when you\'re part of a string.'
};
for (var key in obj) console.log(key); // "lego"
除非您使用有效的(non-negative integer)数组索引,否则请将所有数字属性名称显式指定为字符串。