I have this code. And I don't understand how it works.
let obj = {
valueOf: function () {
return {};
},
toString: function () {
return 222;
}
};
console.log(Number(obj)); //222
According to this source, the conversion algorithm is:
- Call
obj[Symbol.toPrimitive](hint)
if the method exists,- Otherwise if hint is "string" try
obj.toString()
andobj.valueOf()
, whatever exists.- Otherwise if hint is "number" or "default" try
obj.valueOf()
andobj.toString()
, whatever exists.
Hint is number here. Then why is obj.toString()
called? Is there no obj.valueOf()
? Why? What kind of objects have this method? I can't find any useful information about this.
And here's another example:
var room = {
number: 777,
valueOf: function() { return this.number; },
toString: function() { return 255; }
};
console.log( +room ); // 777
Why is obj.valueOf()
called in this case? Why does this method exist here, and doesn't in the first example? How does it work?
From the article you quoted:
Return types
…
The only mandatory thing: these methods must return a primitive, not an object.Historical notes
For historical reasons, iftoString
orvalueOf
returns an object, there’s no error, but such value is ignored (like if the method didn’t exist).
In your first snippet, both methods exists and are tried: first obj.valueOf()
, but since it returns an empty object not a primitive value, obj.toString()
is also called.
In your second snippet, obj.valueOf()
already return the number 777
, which becomes the result.