try*_*sis 59 javascript object-literal node.js template-strings template-literals
为什么JavaScript不允许模板字符串作为对象属性键?例如,当我输入:
foo = {`bar`: 'baz'}
Run Code Online (Sandbox Code Playgroud)
在NodeJS REPL中,它会抛出一个SyntaxError带有长堆栈跟踪的"Unexpected模板字符串".但是,属性值很好,这并不是意料之外的.在浏览器中发生类似的错误,例如,Firebug会抛出SyntaxError"无效的属性ID".
"计算属性名称"中允许使用模板字符串.例如,这在所有支持语法的浏览器中编译得非常好:
var foo = {
[`bar` + 1]: `baz`
};
Run Code Online (Sandbox Code Playgroud)
并创建对象{"bar1": "baz"}.
为什么不允许模板字符串作为文字对象键?是出于性能原因吗?必须在运行时编译模板字符串(如果我错了,请纠正我),这意味着每次遇到此对象时,解释器都必须计算对象名称.考虑到"煮熟的"模板字符串之类的东西,这似乎可能会变慢,尽管我们从ES5开始就有吸气剂和固定器.Firefox没有提到这是一个错误,这就是我发现它意外的原因.将来某个时候会允许语法吗?
Ber*_*rgi 54
为什么不允许模板字符串作为文字对象键?
模板字符串是表达式,而不是文字1.您只能将字符串文字(和标识符)用于属性名称,对于其他所有内容 - 不知道是静态的 - 您需要计算属性名称.
是出于性能原因吗?
不,那不太可能.这是为了简化解析,并且可以轻松区分常量(静态已知)属性名称和动态计算属性名称.
而且大多数情况下,这是一个无人需要的功能.它不会简化或缩短任何东西,你可以用它实现的目标已经成为可能.
将来某个时候会允许语法吗?
不.
1:即使它们被称为"模板文字",从技术上讲它们也不是文字.而且:模板甚至不需要是字符串,它们可以评估任何东西.
dav*_*ell 10
我发布这个答案是为了将@Bergi 非常赞成的评论提升为答案。如果您想使用变量中的动态值作为对象字面量中的对象键,只需使用计算属性:
const dynamicKey = someCondition ? 'someKeyName' : 'otherKeyName';
const obj = {[dynamicKey]: val};
Run Code Online (Sandbox Code Playgroud)
您也可以将其写为:
const obj = {[`${dynamicKey}`]: val};
Run Code Online (Sandbox Code Playgroud)
对象键应该是字符串。
如果作为重点提供的表达式不是字符串,引擎将尝试Coerse它变成一个字符串。
模板字符串不是“coersible”,因此,引擎在尝试 coerse 时抛出错误...
另一方面,数组自然可以转换为字符串,因此可以用作完全合法的键(示例 1)
此外,在创建对象时,包含模板字符串的数组可以用作完全合法的键,因为引擎首先评估模板表达式,然后将数组转换为字符串(示例 2)
见例子:
/* example 1 */ {`foo`: "bar"} // Error: template strs aren't coersible
Run Code Online (Sandbox Code Playgroud)
为了能够使用模板字符串作为对象键,只需将其包装为数组的单个元素:
/* 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"} !!
Run Code Online (Sandbox Code Playgroud)