设置为JavaScript个对象的属性个名字时是否需要引用保留字?

Do reserved words need to be quoted when set as property names of JavaScript objects?

给定一个对象文字或 jQuery(html, attributes) 对象,是否有任何规范规定必须引用保留字或将来的保留字?

或者,例如,可以将 class 设置为对象的 属性 名称,而无需使用引号将 属性 名称括起来,而这种做法与关于标识符、属性 名称或保留字使用的规范?

寻求关于此问题的最终答案以避免混淆。

let objLit = {
  class: 123,
  var: "abc",
  let: 456,
  const: "def",
  import: 789
}

console.dir(objLit);

jQuery("<div>012</div>", {
  class: "ghi"
})
.appendTo("body");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>

相关:

规格

Identifier Names are tokens that are interpreted according to the grammar given in the “Identifiers” section of chapter 5 of the Unicode standard, with some small modifications.
An Identifier is an IdentifierName that is not a ReservedWord

Given an object literal, or jQuery (html, attributes) object, does any specification state that reserved words, or future reserved words MUST be quoted?

否(从 ES5 开始)。

规范中对属性的定义是任意标识符名。 class 是一个非常好的标识符名称。

正如其他人在评论中指出的那样,根据规范,对象文字中的 属性 名称可能是(未加引号的)IdentifierName(此外成为一个字符串等)。 IdentifierName,出于所有实际目的,是 section 7.6.

中给出的任何 Unicode "letters" 序列

注意

产生的语法错误
const {class} = obj;

不是例外。那不是对象文字,这就是问题所在;这是一个赋值(或解构类型),它试图分配一个变量 class。当然你不能,从来没有,也永远不会有变量,这些变量是用保留字命名的。

另请参阅 this blog post,虽然不权威,但却是有关所有事物的可靠、高质量的信息来源 ES5/6/7。

请注意,在 ES3 中,PropertyName 的定义是 Identifier,而不是 IdentifierName在 ES5 中。这阻止了使用 class 等属性,因为 class 不是标识符。正是这一变化允许使用未加引号的保留字作为对象字面量(以及点符号)中的属性。

关于"jQuery objects",一个"jQuery object"只是一个普通的旧JS对象。您是指 jQuery 对象 持有 的 DOM 元素吗?它们是原生对象和 JS 对象的一种混合体。作为 JS 对象,它们可以具有属性。但是,它们不能以对象文字形式编写,因此这个问题并不真正适用于它们。 (作为原生 (DOM) 对象,它们可以具有属性,后一种情况不在 JS 规范中。)

ECMAScript 5+

不,自 ECMAScript 5 以来不需要引号。原因如下:

正如您在 post 中提到的,来自 ECMAScript® 5.1 Language Specification:

7.6 Identifier Names and Identifiers

Identifier Names are tokens that are interpreted according to the grammar given in the “Identifiers” section of chapter 5 of the Unicode standard, with some small modifications. An Identifier is an IdentifierName that is not a ReservedWord (see 7.6.1).

[...]

Syntax

Identifier ::
  IdentifierName but not ReservedWord

根据规范,ReservedWord 是:

7.6.1 Reserved Words

A reserved word is an IdentifierName that cannot be used as an Identifier.

Syntax

ReservedWord :: 
  Keyword
  FutureReservedWord
  NullLiteral
  BooleanLiteral

这包括关键字、未来关键字、null 和布尔文字。完整名单如下:

7.6.1.1 Keywords

break    do       instanceof typeof
case     else     new        var
catch    finally  return     void
continue for      switch     while
debugger function this       with
default  if       throw 
delete   in       try   

7.6.1.2 Future Reserved Words

class enum   extends super
const export import

7.8.1 Null Literals

null

7.8.2 Boolean Literals

true
false

以上(第 7.6 节)暗示 IdentifierNames 可以是 ReservedWords,并且根据 object initializers 的规范:

11.1.5 Object Initialiser

[...]

Syntax

ObjectLiteral :
  { }
  { PropertyNameAndValueList }
  { PropertyNameAndValueList , }

其中 PropertyName 是,根据规范:

PropertyName :
  IdentifierName
  StringLiteral
  NumericLiteral

如您所见,PropertyName 可能是 IdentifierName,因此 ReservedWord 可以是 PropertyName。这最终告诉我们,通过规范,允许有 ReservedWords,例如 classvar 作为 PropertyNames不带引号,就像字符串文字或数字文字一样。


ECMAScript <5

要更深入地了解为什么在 ES5 之前的早期版本中不允许这样做,您必须查看 PropertyName 是如何定义的。根据 ECMAScript® 3 Language Specification:

PropertyName :
  Identifier
  StringLiteral
  NumericLiteral

如您所见,PropertyName 是一个 Identifer - 而不是 IdentifierName,因此导致 ReservedWord 不能像 PropertyName 一样.

这个答案无法与已经给出的答案相提并论,但我还是很乐意插话。

在我的代码中,我更喜欢始终引用键,例如:

var o;

o = {
  "label": "Hello",
  "index": 3
};

这样就不会出现奇怪的名字或保留关键字的问题了。此外,所有对象字面量都以非常接近有效 JSON 的样式编写,作为额外的奖励复制+粘贴到单独的 JSON 文件(反之亦然)可以非常快地完成。

今天,我认为这是干净代码的必备风格。