【问题标题】:Dynamically adding a variable whose name leads with a numeric value动态添加名称以数值开头的变量
【发布时间】:2012-01-26 03:37:26
【问题描述】:

我注意到,如果我尝试使用以数值开头的键名创建一个对象,则会引发错误(与此处概述的 JavaScript 命名相关:What characters are valid for JavaScript variable names?)。但是,我注意到如果我这样做,我仍然可以动态添加这样的变量名

失败:

object.1foo = "bar";

失败:

object = {
  1foo: "bar"
}

成功:

object["1foo"] = bar;

这是为什么呢?

【问题讨论】:

  • 它们是语义上不同的结构,恰好对运行时环境意味着相同的东西。

标签: javascript


【解决方案1】:

访问object["1foo"] 时,您创建的不是标识符,而是在对象中查找值的键。

标识符不能以数字开头,键没有任何这样的规范(出于某种“明显”的原因。

标识符不是值,键(在本文中描述的意义上)不是标识符。

在执行{"1foo": 123} 时,您并没有使1foo 成为正确的标识符,它是string 类型的右值变量。


根据 ECMA 标准

7.6 标识符名称和标识符

标识符 ::

  • IdentifierName 但不是 ReservedWord

标识符名称 ::

  • 标识符开始
  • 标识符名称、标识符部分

标识符开始 ::

  • Unicode 字母
  • $
  • _
  • \UnicodeEscapeSequence

标识符部分 ::

  • 标识符开始
  • UnicodeCombiningMark
  • UnicodeDigit
  • UnicodeConnectorPunctuation

...

11.1.5 对象初始化器

PropertyName [可以是以下任何一种]:

  • 标识符名称
  • 字符串文字
  • 数字文字

【讨论】:

    【解决方案2】:

    您不应混合使用有效的变量名和有效的属性名。在您的情况下,您正在处理对象属性,并且根据 ECMAScript 规范的 "Object Initialiser" 部分,对象属性名称应该是 valid identifier,或 valid string,或 有效号码

    ObjectLiteral :
        {}
        { PropertyNameAndValueList }
    
    PropertyNameAndValueList :
        PropertyName : AssignmentExpression
        PropertyNameAndValueList , PropertyName : AssignmentExpression
    
    PropertyName :
        Identifier
        StringLiteral
        NumericLiteral 
    

    由于1foo 不是有效标识符(请参阅"Identifiers" 部分),您不能直接使用它来定义属性。但是(除了您在问题中描述的方式之外)您可以使用字符串属性名称来做到这一点:

    object = { '1foo': 'bar' }
    

    【讨论】:

      【解决方案3】:

      标识符的形成方式是一个句法规则,也就是说,它只适用于解析程序源代码的情况。在运行时,对象字段的名称只是任意字符串,引擎并不关心从解析器的角度来看这些字符串是否“有效”:

      obj = {}
      
      obj["foo"] - ok
      obj["1xx"] - ok
      obj["{{{"] - ok
      obj["   "] - ok
      

      【讨论】:

        【解决方案4】:

        当您执行object["1foo"] 时,您实际上是在转义属性的名称,这就是它起作用的原因。

        另一个也失败了,因为 1foo 没有被转义,它的形式相同。

        如果您想使用标准点符号(例如 object.property)访问对象成员,则不允许使用除 _ 或 $ 之外的任何特殊字符;除此之外,名称不能以数字开头。对于所有其他情况,您必须使用方括号和引号来访问对象元素。

        【讨论】:

          猜你喜欢
          • 2011-05-03
          • 1970-01-01
          • 1970-01-01
          • 2018-02-23
          • 1970-01-01
          • 2022-11-16
          • 2021-06-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多