10
const num = 42
const str = `My number is ${num}`

In this code what guarantee do I have about the conversion of num to a string ?

Is it guaranteed to just call its toString() method or could the conversion be done in another way ?

Drax
  • 12,682
  • 7
  • 45
  • 85
  • 2
    The conversion is always done by `String(num)`. That *might* call `.toString()` or it might not, there are many ways. – Bergi Jun 24 '20 at 13:02
  • 1
    @Bergi plz write an answer if you have the info for this – Drax Jun 25 '20 at 09:17

3 Answers3

10

Untagged templates use the ECMAScript ToString() abstract operation. The logic of template literal evaluation is spread over several sections which makes it difficult to follow, so I'll just post a link to it: https://tc39.es/ecma262/#sec-template-literals-runtime-semantics-evaluation

ToString(argument) uses a table instead of algorithmic steps, so I'll write out some pseudocode here:

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'));
}

As you can see, no js execution happens at all for primitive values, the engine internally creates a string representation. For objects, we go into the ToPrimitive() algorithm.

ToPrimitive(input, PreferredType) will try to get the Symbol.toPrimitive method from input, and if it's present, call it with the given PreferredType hint. If input does not have a Symbol.toPrimitive property, it falls back to OrdinaryToPrimitive.

OrdinrayToPrimitive(O, hint) will try to call the toString and valueOf methods. If hint is 'string', it try to call toString method first, otherwise it will try to call the valueOf method first. If either of those methods are present and they don't return an object, their return value will be used. If neither are present or they both return objects, a TypeError will be thrown.

So to answer your original question, converting 42 will not call any other methods. The engine will internally create a string representation ('42'), and use that.

snek
  • 1,980
  • 1
  • 15
  • 29
1

Yes. If either value is not a string, it’ll be converted to a string using the usual rules. For example, if action is an object, its .toString() method will be called.

Read the full article from mozilla https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/

thatcoder
  • 367
  • 2
  • 9
1

Yes, it is a function of Object Primitive as described in MDN

Edit: ECMA specification is expression as described here.

Again in MDN - Template literal is written:

The default function just concatenates the parts into a single string

Greedo
  • 3,438
  • 1
  • 13
  • 28
  • 3
    Sure it is, but who says it is going to be called in template literals ? – Drax Jun 24 '20 at 12:51
  • 1
    @Drax I added more details – Greedo Jun 24 '20 at 13:04
  • 4
    This is not the question, the question is not about the concatenation, the question is about parts that are not string, like a number for example, how do we know it is converted with the `toString()` method and not in another way ? – Drax Jun 25 '20 at 09:19