作为对象属性名称的模板字符串

为什么 JavaScript 不允许将模板字符串作为对象属性键?例如,当我输入:

foo = {`bar`: 'baz'}

在 NodeJS REPL 中,它会抛出一个带有“意外模板字符串”的长堆栈跟踪。但是,属性值很好,这并不出乎意料。类似的错误发生在浏览器中,例如,Firebug会抛出一个带有“无效属性ID”的。SyntaxErrorSyntaxError

“计算属性名称”中允许使用模板字符串。例如,这在支持以下语法的所有浏览器中编译得非常好:

var foo = {
    [`bar` + 1]: `baz`
};

并创建对象 。{"bar1": "baz"}

为什么不允许将模板字符串作为文本对象键?是出于性能原因吗?模板字符串必须编译,可能是在运行时(如果我错了,请纠正我),这意味着每次遇到这个对象时,解释器都必须计算对象名称。考虑到像“煮熟”模板字符串这样的东西,这似乎可能会变慢,尽管我们从ES5开始就有了getter和setter。Firefox没有提到这是一个错误,这就是为什么我发现它出乎意料的原因。将来某个时候会允许使用该语法吗?


答案 1

为什么不允许将模板字符串作为文本对象键?

模板字符串是表达式,而不是文本1。您只能将字符串文本(和标识符)用于属性名称,对于其他所有内容(未知为静态),则需要计算属性名称。

是出于性能原因吗?

不,这不太可能。这是为了简化解析,并可以轻松地区分常量(静态已知)属性名称和动态计算的属性名称。

大多数情况下,这是一个没有人需要的功能。它不会简化或缩短任何东西,你用它实现的目标已经是可能的。

将来某个时候会允许使用该语法吗?

不。

1:即使它们被称为“模板文本”,从技术上讲,它们也不是文本。而且:模板甚至不需要是字符串,它们可以评估为任何东西。


答案 2

对象键应为字符串。

如果作为键提供的表达式不是字符串,则引擎将尝试将其转换为字符串。

模板字符串不是“可协调的”,hense,引擎会抛出一个错误,试图协调它们(示例1)

另一方面,数组自然可以与字符串兼容,因此可以用作完全合法的键。

此外,在创建对象时,包含模板字符串的数组可以用作完全合法的键,因为引擎首先计算模板表达式,然后将数组归为字符串(示例 2)

查看示例:

    /* example 1 */ {`foo`: "bar"}   // Error: template strs aren't coersible

为了能够使用模板字符串作为对象键,只需将其包装为数组的单个元素:

    /* example 2 */ {[`foo`]: "bar"} /* OK: {foo: "bar"}, the internal `foo` 
                                           template is first resolved to a native 
                                           "foo" string, resulting in array ["foo"],
                                           which then coersed to the "foo" key.*/
    
    /* example 3 */ const obj = {foo: "bar"}
                        const obj1 = {[obj.foo]: "bar"} // OK: {bar: "bar"} !!