【问题标题】:Valid javascript object property names有效的 javascript 对象属性名称
【发布时间】:2025-12-18 23:30:01
【问题描述】:

我正在尝试找出对 javascript 对象的属性名称有效的内容。例如

var b = {}
b['-^colour'] = "blue";     // Works fine in Firefox, Chrome, Safari
b['colour'] = "green";      // Ditto
alert(b['-^colour']);       // Ditto
alert(b.colour);            // Ditto
for(prop in b) alert(prop); // Ditto
//alert(b.-^colour);     // Fails (expected)

这个post 详细说明了有效的javascript 变量名,而'-^colour' 显然是无效的(作为变量名)。这同样适用于对象属性名称吗?看看上面我正在努力解决如果

  1. b['-^colour'] 无效,但可以在所有浏览器中正常工作,我不应该相信它会继续工作

  2. b['-^colour'] 是完全有效的,但它只是一种只能以这种方式访问​​的形式 - (它支持,所以对象可以用作地图吗?)

  3. 别的东西

顺便说一句,javascript 中的全局变量可能在顶层声明为

var abc = 0;

但也可以用

创建(据我所知)
window['abc'] = 0;

以下所有浏览器均适用

window['@£$%'] = "bling!";
alert(window['@£$%']);

这有效吗?这似乎与变量命名规则相矛盾 - 或者我没有在那里声明变量?变量和对象属性名有什么区别?

【问题讨论】:

    标签: javascript


    【解决方案1】:
    1. 每次创建全局变量时,实际上都会创建一个全局对象的新成员(在浏览器环境中为window,在Node.js 中为global,等等.)。这就是为什么window.x 与(全局)var xthis.x 或只是x 完全相同。

    2. 理解 JavaScript 像地图一样的对象 是非常正确的,因为:a) 您可以动态添加新元素 - 随时; b) 元素可以有任何名称 - 也包括特殊字符,c) 您可以尝试访问对象/地图的不存在元素,这不是错误,d) 您可以从对象中删除元素。

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

    【讨论】:

      【解决方案2】:

      对象属性命名规则和变量命名规则是分开的。该标准仅“保留”少数属性名称(例如prototypeconstructor,IIRC),但除此之外,任何字符串都可以。

      当然,除非执行环境(即浏览器)决定添加更多魔法属性。 (我听说设置 __proto__ 会以非常奇怪的方式破坏一些东西)

      【讨论】:

      • 感谢 Matti - 很难确定谁给出答案,两者都回答了,但有不同的(有用的)信息 - 选择了第一个答案。干杯。
      • 当您将 __proto__ 设置为 null 时,如果您需要将其作为值对的简单哈希表,除了原型链(因此它是一个更快的属性查找)之外,这会破坏什么?跨度>
      【解决方案3】:

      是的,对象可以用作地图,任何字符串都可以是属性名称。正如您所发现的,某些属性只能使用括号语法访问。

      window['abc']
      

      正在访问一个属性。它不是一个变量,即使它(在全局级别)引用相同的值:

      abc
      

      【讨论】:

      • "对象属性名称可以是任何有效的 JavaScript 字符串,也可以是任何可以转换为字符串的内容,包括空字符串。但是,任何不是有效 JavaScript 标识符的属性名称(例如,具有空格或连字符或以数字开头的属性名称)只能使用方括号表示法访问。” (MDN)
      • Márton 提出了一个非常重要的观点。 虽然起初看起来好像任何 JS 对象都可以将任何东西作为有效的对象键,但它情况并非如此——Márton 正确地指出,这些属性键实际上已转换为字符串。考虑var x=new function X(){};var y=new function Y(){};obj={x:true};——obj[y]将输出true,因为xy在用作对象键时都被转换为相同的字符串@987654331 @
      • 要清楚,以我之前的评论为例,obj[x] === obj[y] === obj["[object Object]"]
      • 我会指出限制标识符名称的原因(即使 JS 可能在内部将任何字符串作为变量或属性标识符处理)主要是为了避免语法歧义。考虑一个带有破折号的属性名称:x=obj.my-prop。如果这是一个名为“my-prop”的属性,或者是否打算从“obj.my”中减去一个变量“prop”,则(读者和解析器都不清楚)。 x=obj["my-prop"] 清楚地表明名称是一个字符串。