console.log("12"+ {"x":"1",toString(){return 10;},valueOf(){return 90}});
In the above expression why toString() method is not called? As per the algorithm if either the left or right side there is string then we call ToString() with hint as "String" for another side and if hint is "String" then the toString() method will be called first and then the valueOf() method. But the above expression is given answer as "1290" mean valueOf() is called.
Algorithm for additive expression: -
12.8.3The Addition Operator ( + )
NOTE
The addition operator either performs string concatenation or numeric addition.
12.8.3.1Runtime Semantics: Evaluation
AdditiveExpression:AdditiveExpression+MultiplicativeExpression
Let lref be the result of evaluating AdditiveExpression.
Let lval be ? GetValue(lref).
Let rref be the result of evaluating MultiplicativeExpression.
Let rval be ? GetValue(rref).
Let lprim be ? ToPrimitive(lval).
Let rprim be ? ToPrimitive(rval).
If Type(lprim) is String or Type(rprim) is String, then
Let lstr be ? ToString(lprim).
Let rstr be ? ToString(rprim).
Return the string-concatenation of lstr and rstr.
Let lnum be ? ToNumber(lprim).
Let rnum be ? ToNumber(rprim).
Return the result of applying the addition operation to lnum and rnum. See the Note below 12.8.5.
ToString rules:
7.1.12ToString ( argument )
The abstract operation ToString converts argument to a value of type String according to Table 11:
Table 11: ToString Conversions
ToString conversion table:
According to the ToString Conversion table if there is object then hint "String" will be used.
Why is valueOf() method preferred?
As I read the spec,
13.8.1 The Addition Operator ( + ) specifies this in terms of ApplyStringOrNumericBinaryOperator
where
lval
is "12"
opText
is +
rval
is {"x":"1",toString(){return 10;},valueOf(){return 90}})
As I see it, rprim := ToPrimitive(rval)
there ends up invoking OrdinaryToPrimitive(..., "number")
, which prefers valueOf
to toString
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With