What is the difference between them?
Both that, and that deduces to us a line which we specifies in return , thus valueOf if explicitly specified, erases toString .
I read a couple of sources, but did not understand the difference. If possible, in more detail, please.

  • the difference is when these functions are called, but what about stringOf ? maybe toString ? - Grundy

2 answers 2

I would venture to assume that you mean the valueOf and toString functions.
The difference between them is a little blurred, but clear:

  • valueOf used to convert an object numerically ( foo + 42 , ++bar , etc.). But it is far from all objects (that is, it is, but returns the object itself, therefore it is ignored) and is obliged to return a primitive, otherwise it will be ignored and toString will be called.
  • toString used for string object conversion ( alert(foo) ). There are all objects, usually not very informative ( [object Object] ), but it is very convenient if you need to overload the operator, for example (in JS there is no overload / creation of operators). Also obliged to return primitive.

Read more .
The use of these operators has nuances (as everywhere in JS , probably, this insidious language, however!), Which are easier to learn from the specification.

  • Probably I didn’t catch much of a difference, because this and that returns a primitive, I can’t just write return i foo + 42 in both here and there? in the case of foo, the string then concatenates and vivests the same thing in the case of valueOf, what in the case of toString? - Artem Palamarchuk 6:51 pm
  • @ArtemPalamarchuk, it's easier, probably, to understand the meaning of the methods: value - value, string - string. That is, in operations, it is as if the value is needed, and where you need to draw an object with text - we use a string. foo + 42 -> valueOf ; alert(foo) -> toString . - user207618 7:03 pm
  • I understood, well, thank you - Artem Palamarchuk

If it is not clear in the sources, you should refer to the specification :
which of these methods will be called is defined inside the abstract operation ToPrimitive , which is performed in almost all operations with objects, for example: arithmetic operations, comparison operations, etc.

ToPrimitive ( input [, PreferredType] ) operation ToPrimitive ( input [, PreferredType] )

When Type (input) is Object , the following steps are taken:

  1. If PreferredType is absent, hint will be "default" .
  2. If PreferredType tells String , the hint will be "string" .
  3. If PreferredType prompts Number , the hint will be "number" .
  4. Let exoticToPrim be a GetMethod (input, @@ toPrimitive) .
  5. If exoticToPrim is not undefined , then

    1. result will be Call (exoticToPrim, input, "hint") . ReturnIfAbrupt (result).
    2. If Type (result) is not Object , return result .
    3. Throw a TypeError exception.
  6. If hint = "default" , hint will be "number" .

  7. Return the result OrdinaryToPrimitive (input, hint) .

As can be seen from the algorithm, if the object does not have an internal exotic function, OrdinaryToPrimitive will be called to bring it to a primitive value.

When calling the abstract operation OrdinaryToPrimitive with arguments O and hint , the following steps will be performed:

  1. Type check: Type (O) - Object
  2. Type check: Type (hint) is a String and the value is "string" or "number" .
  3. If hint = "string" , then
    1. methodNames will be a list of "" toString "," valueOf "" .
  4. Otherwise
    1. methodNames will be a list of "" valueOf "," toString "" .
  5. For each name from methodNames
    1. method will be Get (O, name) .
    2. If IsCallable (method) = true , then
    3. result = Call (method, O) .
    4. If Type (result) is not Object , return result .
  6. Throw a TypeError exception.

Note: When ToPrimitive is called without the hint parameter, the behavior is the same as in the case of passing the hint Number value. However, objects can override these behaviors by defining the @@ toPrimitive method. Of the objects in the current specification, only Date and Symbol objects override the default behavior. Date objects are considered a call without passing hint , as if they had passed a String .

  • one
    I immensely bow down to specifications, but their dry language is extremely uninformative. If you, of course, do not collect the interpreter. - user207618
  • @Other, I think this is the case when you can look at the algorithm once and understand how it works, what to learn under what types and what will be called - Grundy
  • May be. Although the study of such algorithms, perhaps more appropriate when creating an interpreter, rather than a simple work with the language. But I read it with pleasure. - user207618
  • Thanks for the answer. I didn’t understand a bit: “if an object has no intrinsic exotic function”, is this about @@toPrimitive ? This function can not be declared yourself, the language itself only can? - Ilya Zelenko
  • one
    @ IlyaZelenko, you can, for this there is a special Symbol: Symbol.toPrimitive - Grundy