JavaScript 模板文字是否保证调用 toString()?

Dra*_*rax 4 javascript tostring language-lawyer template-literals

const num = 42
const str = `My number is ${num}`
Run Code Online (Sandbox Code Playgroud)

在这段代码中,我对转换num为 a有什么保证string

是保证只调用它的toString()方法还是可以用另一种方式进行转换?

sne*_*nek 5

未标记的模板使用 ECMAScriptToString()抽象操作。模板文字评估的逻辑分布在几个部分,这使得它很难理解,所以我只发布一个链接:https : //tc39.es/ecma262/#sec-template-literals-runtime-semantics-评估

ToString(argument) 使用表格而不是算法步骤,所以我将在这里写出一些伪代码:

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'));
}
Run Code Online (Sandbox Code Playgroud)

如您所见,对于原始值根本没有 js 执行,引擎在内部创建了一个字符串表示。对于对象,我们进入ToPrimitive()算法。

ToPrimitive(input, PreferredType)将尝试从 获取Symbol.toPrimitive方法input,如果存在,则使用给定的PreferredType提示调用它。如果input没有Symbol.toPrimitive属性,则回退到OrdinaryToPrimitive

OrdinrayToPrimitive(O, hint)将尝试调用toStringvalueOf方法。如果hint'string',它会先尝试调用toString方法,否则会先尝试调用valueOf方法。如果存在这些方法中的任何一个并且它们不返回对象,则将使用它们的返回值。如果两者都不存在或它们都返回对象,则将抛出 TypeError。

因此,要回答您的原始问题,转换42不会调用任何其他方法。引擎将在内部创建一个字符串表示 ( '42'),并使用它。