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

问题描述 投票:0回答:4
const num = 42
const str = `My number is ${num}`

在这段代码中,我对

num
string
的转换有何保证?

是否保证只调用它的

toString()
方法或者可以通过其他方式完成转换?

javascript language-lawyer tostring template-literals
4个回答
10
投票

未标记模板使用 ECMAScript

ToString()
抽象操作。模板文字评估的逻辑分布在几个部分,这使得它很难理解,所以我只发布一个链接: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'));
}

如您所见,对于原始值根本不会执行任何 js,引擎内部会创建一个字符串表示形式。对于对象,我们进入

ToPrimitive()
算法。

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

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

因此,为了回答您原来的问题,转换

42
不会调用任何其他方法。引擎将在内部创建一个字符串表示形式 (
'42'
),并使用它。


1
投票

是的。如果其中一个值不是字符串,则会使用通常的规则将其转换为字符串。例如,如果action是一个对象,它的.toString()方法将被调用。

阅读 mozilla 的全文 https://hacks.mozilla.org/2015/05/es6-in-deep-template-strings-2/


1
投票

是的,它是

Object
原语的函数,如 MDN

中所述

编辑: ECMA 规范是

expression
,如此处所述。

再次在 MDN - 模板文字中写道:

默认函数只是将各个部分连接成一个字符串


0
投票

toString
在 JavaScript 模板文本中不被调用

let p = 123;
let c = p.constructor;
if (typeof c.prototype.toString2 !== 'function') {
    c.prototype.toString2 = c.prototype.toString;
    c.prototype.toString = function () {
        console.log("toString is called")
        return this.toString2();
    }
}
console.log("Test 1");
console.log(p + "")
console.log("Test 2");
console.log(p.toString())
console.log("Test 3");
console.log(`${p}`)
console.log("Test 4");
typeof p === 'number' && console.log(p.toFixed())
© www.soinside.com 2019 - 2024. All rights reserved.