JavaScript 模板文字保证调用 toString() 吗?
Are JavaScript template literals guaranteed to call toString()?
const num = 42
const str = `My number is ${num}`
在这段代码中,我对 num
到 string
的转换有什么保证?
是否保证只调用它的 toString()
方法,或者可以通过其他方式完成转换?
是的。如果任一值不是字符串,它将使用通常的规则转换为字符串。例如,如果 action 是一个对象,它的 .toString() 方法将被调用。
阅读来自 mozilla 的完整文章
https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/
是的,它是 Object
原语的函数,如 MDN
中所述
编辑:
ECMA 规范是 expression
,如 here 所述。
默认函数只是将各个部分连接成一个字符串
无标记模板使用 ECMAScript ToString()
抽象操作。模板文字评估的逻辑分布在几个部分,这使得它很难理解,所以我只是 post 一个 link 到它:https://tc39.es/ecma262/#sec-template-literals-runtime-semantics-evaluation
ToString(argument)
使用 table 而不是算法步骤,所以我会在这里写一些伪代码:
switch (Type(argument)) {
case 'Undefined':
return 'undefined';
case 'Null':
return 'null';
case 'Boolean':
return argument ? 'true' : 'false';
case 'Number':
return Number::toString(argument);
case 'String':
return argument;
case 'Symbol':
throw new TypeError();
case 'BigInt':
return BigInt::toString(arugment);
case 'Object':
return ToString(ToPrimitive(argument, 'string'));
}
如您所见,原始值根本没有执行任何 js,引擎在内部创建了一个字符串表示。对于对象,我们进入 ToPrimitive()
算法。
ToPrimitive(input, PreferredType)
将尝试从 input
获取 Symbol.toPrimitive
方法,如果存在,则使用给定的 PreferredType
提示调用它。如果 input
没有 Symbol.toPrimitive
属性,它会退回到 OrdinaryToPrimitive
.
OrdinrayToPrimitive(O, hint)
将尝试调用 toString
和 valueOf
方法。如果hint
是'string'
,它会先尝试调用toString
方法,否则会先尝试调用valueOf
方法。如果存在这些方法中的任何一个并且它们不是 return 对象,则将使用它们的 return 值。如果两者都不存在或它们都是 return 个对象,则会抛出 TypeError。
所以要回答你原来的问题,转换 42
不会调用任何其他方法。引擎将在内部创建一个字符串表示形式 ('42'
),并使用它。
const num = 42
const str = `My number is ${num}`
在这段代码中,我对 num
到 string
的转换有什么保证?
是否保证只调用它的 toString()
方法,或者可以通过其他方式完成转换?
是的。如果任一值不是字符串,它将使用通常的规则转换为字符串。例如,如果 action 是一个对象,它的 .toString() 方法将被调用。
阅读来自 mozilla 的完整文章 https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/
是的,它是 Object
原语的函数,如 MDN
编辑:
ECMA 规范是 expression
,如 here 所述。
默认函数只是将各个部分连接成一个字符串
无标记模板使用 ECMAScript ToString()
抽象操作。模板文字评估的逻辑分布在几个部分,这使得它很难理解,所以我只是 post 一个 link 到它:https://tc39.es/ecma262/#sec-template-literals-runtime-semantics-evaluation
ToString(argument)
使用 table 而不是算法步骤,所以我会在这里写一些伪代码:
switch (Type(argument)) {
case 'Undefined':
return 'undefined';
case 'Null':
return 'null';
case 'Boolean':
return argument ? 'true' : 'false';
case 'Number':
return Number::toString(argument);
case 'String':
return argument;
case 'Symbol':
throw new TypeError();
case 'BigInt':
return BigInt::toString(arugment);
case 'Object':
return ToString(ToPrimitive(argument, 'string'));
}
如您所见,原始值根本没有执行任何 js,引擎在内部创建了一个字符串表示。对于对象,我们进入 ToPrimitive()
算法。
ToPrimitive(input, PreferredType)
将尝试从 input
获取 Symbol.toPrimitive
方法,如果存在,则使用给定的 PreferredType
提示调用它。如果 input
没有 Symbol.toPrimitive
属性,它会退回到 OrdinaryToPrimitive
.
OrdinrayToPrimitive(O, hint)
将尝试调用 toString
和 valueOf
方法。如果hint
是'string'
,它会先尝试调用toString
方法,否则会先尝试调用valueOf
方法。如果存在这些方法中的任何一个并且它们不是 return 对象,则将使用它们的 return 值。如果两者都不存在或它们都是 return 个对象,则会抛出 TypeError。
所以要回答你原来的问题,转换 42
不会调用任何其他方法。引擎将在内部创建一个字符串表示形式 ('42'
),并使用它。