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

时间:2016-10-24 00:55:32

标签: javascript language-lawyer ecmascript-5

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

相关:

规范

  

标识符名称是根据标识解释的标记   “Identifiers” section of chapter 5 of the Unicode standard中给出的语法,稍作修改   标识符是不是ReservedWord

的标识符名称

3 个答案:

答案 0 :(得分:25)

ECMAScript 5 +

不,自ECMAScript 5以来不需要引号。这就是原因:

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

  

7.6标识符名称和标识符

     

标识符名称是根据Unicode标准第5章“标识符”部分中给出的语法进行解释的标记,并进行了一些小的修改。 Identifier IdentifierName不是ReservedWord(请参阅7.6.1)。

     

[...]

     

<强>语法

Identifier ::
  IdentifierName but not ReservedWord

根据规范,ReservedWord是:

  

7.6.1保留字

     

保留字是IdentifierName,不能用作Identifier

     

<强>语法

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
     

7.8.2布尔文字

true
false

以上(第7.6节)暗示IdentifierName s可以是ReservedWord s,并且来自object initializers的规范:

  

11.1.5对象初始化程序

     

[...]

     

<强>语法

ObjectLiteral :
  { }
  { PropertyNameAndValueList }
  { PropertyNameAndValueList , }

PropertyName在哪里,按规范:

PropertyName :
  IdentifierName
  StringLiteral
  NumericLiteral

如您所见,PropertyName可能是IdentifierName,因此允许ReservedWordPropertyName。这最终告诉我们, by specification ,允许将ReservedWord classvar PropertyName作为PropertyName取消引用,就像字符串文字或数字文字。

ECMAScript&lt; 5

为了更深入地了解为什么在ES5之前的版本中不允许这样做,您必须查看PropertyName : Identifier StringLiteral NumericLiteral 的定义方式。根据{{​​3}}:

PropertyName

正如您所看到的,IdentiferIdentifierName - 而不是ReservedWord,从而导致PropertyName无法{{1}} s。< / p>

答案 1 :(得分:2)

  

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

否(从ES5开始)。

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

正如其他人在评论中指出的那样,根据规范,对象文字中的属性名称可以是(未引用的) IdentifierName (除了是字符串等)。出于所有实际目的, IdentifierName section 7.6中给出的任何Unicode“字母”序列。

请注意

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

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

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

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

关于“jQuery对象”,“jQuery对象”只是一个普通的旧JS对象。你的意思是jQuery对象持有的DOM元素?它们是本机对象和JS对象的混合体。作为JS对象,它们可以具有属性。但是,它们不能以对象字面形式编写,因此问题并不真正适用于它们。 (作为本机(DOM)对象,它们可以具有属性,后一种情况不包含在JS规范中。)

答案 2 :(得分:1)

这个答案不能与那些已经给出的答案竞争,但我仍然喜欢这个答案。

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

var o;

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

这样,甚至不会出现奇怪名称或保留关键字的问题。此外,所有对象文字都以非常接近有效JSON的样式编写,因为可以非常快速地将额外的奖励副本+粘贴到单独的JSON文件中(反之亦然)。

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