当设置为JavaScript对象的属性名时,保留字是否需要加引号

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

本文关键字:保留字 是否 加引号 设置 JavaScript 对象 属性      更新时间:2023-09-26

给定一个对象字量,或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>

相关:

  • 带引号和不带引号的对象键有什么区别?

  • 评论

规范

    7.6标识符名称和标识符:

标识符名称是根据Unicode标准第5章"标识符"部分给出的语法标准,加上一些小修改
Identifier是一个IdentifierName 而不是ReservedWord

ECMAScript 5 +

不,从ECMAScript 5开始就不需要引号了。原因:

正如你的帖子中提到的,来自ECMAScript®5.1语言规范:

7.6标识符名称和标识符

标识符名称是根据Unicode标准第5章"标识符"部分给出的语法进行解释的标记,并进行了一些小修改。Identifier是指非ReservedWordIdentifierName(见7.6.1)。

[…]

语法

Identifier ::
  IdentifierName but not ReservedWord

根据规范,ReservedWord为:

7.6.1保留字

保留字是不能用作IdentifierIdentifierName

语法

ReservedWord :: 
  Keyword
  FutureReservedWord
  NullLiteral
  BooleanLiteral

这包括关键字、未来关键字、null和布尔字面值。完整列表如下:

7.6.1.1关键词
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未来保留字
class enum   extends super
const export import

7.8.1 Null literal

null
7.8.2布尔字面值
true
false

上面(第7.6节)意味着IdentifierName s可以是ReservedWord s,并且从对象初始化式的规范来看:

11.1.5对象初始化器

[…]

语法

ObjectLiteral :
  { }
  { PropertyNameAndValueList }
  { PropertyNameAndValueList , }

其中PropertyName为,按规格:

PropertyName :
  IdentifierName
  StringLiteral
  NumericLiteral

可以看到,PropertyName可以是IdentifierName,因此允许ReservedWord s是PropertyName s。这最终告诉我们,通过规范,允许将ReservedWord(如classvar)作为PropertyName(不加引号),就像字符串字面值或数字字面值一样。


ECMAScript & lt; 5

要更深入地了解为什么在ES5之前的版本中不允许这样做,你必须看看PropertyName是如何定义的。根据ECMAScript®3语言规范:

PropertyName :
  Identifier
  StringLiteral
  NumericLiteral

可以看到,PropertyNameIdentifer而不是IdentifierName,因此导致ReservedWord s不能作为PropertyName s。

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

没有(从ES5开始)。

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

正如其他人在评论中指出的那样,根据规范,对象文字中的属性名可以是(不加引号的)IdentifierName(除了作为字符串等)。IdentifierName为所有实际用途,是任何Unicode"字母"序列,如第7.6节所述。

注意

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

而不是异常。这不是对象字面意思,这才是问题所在;它是一个赋值(或析构类),它试图赋值一个变量 class。当然,你不能,从来没有,也永远不会有变量用保留字命名。

请参阅这篇博文,虽然不具有权威性,但它是关于ES5/6/7所有事情的可靠、高质量的信息来源。

注意,在ES3中,PropertyName的定义是Identifier,而不是ES5中的IdentifierName。由于class不是标识符,因此无法使用class之类的属性。正是这个改变允许在对象字面量(以及点表示法)中使用未加引号的保留字作为属性。

关于"jQuery对象","jQuery对象"只是一个常规的旧JS对象。你的意思是DOM元素由jQuery对象持有吗?它们是原生对象和JS对象的混合体。作为JS对象,它们可以拥有属性。然而,它们不能以对象字面量的形式书写,所以这个问题并不真正适用于它们。(作为原生(DOM)对象,它们可以有属性,后一种情况没有被JS规范覆盖。)

这个答案无法与已经给出的答案竞争,但我还是想加入进来。

在我的代码中我喜欢总是引用键,例如:

var o;
o = {
  "label": "Hello",
  "index": 3
};
这样,甚至不会出现奇怪的名称或保留关键字的问题。此外,所有对象文字都以非常接近有效JSON的风格编写,因为可以非常快速地将复制+粘贴到单独的JSON文件中(反之亦然)。

今天,我认为这是整洁代码的必备样式。