Reputation: 241
Some code for example.
let a = 1
a.__proto__.toString = function(){ return 'test'}
a.toString()
//"test"
a + '2'
//"12"
I realy can't understand where is toString
method stored.
If I do this with mutable objects I got
let o = {}
o.__proto__.toString = function(){ return 'test'}
o.toString()
//"test"
o + '2'
//"test2"
That works as I expected.
So the question is where toString
of Number
or other immutable types stored and called when type conversion occurs.
Upvotes: 21
Views: 1089
Reputation: 816364
So the question is where toString of Number or other immutable types stored and called when type conversion occurs
It's stored on Number.prototype
. The more important question is:
How is a number converted to a string when doing
1 + 'a'
?
Not via the toString
method!
The toString
method is only used when converting an object to a primitive value. However, a number is already a primitive value. Instead there is an internal ToString
routine that is called to convert the number to a string. The details can be found in the ES2017 specification at 12.8.3, 7.7.12 and 7.1.12.1 . The details are a bit long, but it starts like this:
- If
m
isNaN
, return the String"NaN"
.- If
m
is+0
or-0
, return the String"0"
.- ...
as you can see, these are very specific instructions for how to convert a number value to a string, which have nothing to do with the actual toString
method defined on Number.prototype.toString
.
Upvotes: 28
Reputation: 224886
The issue here isn’t with Number.prototype
; it’s just that Number.prototype.toString
isn’t called when converting numbers to strings. JavaScript uses its internal ToString operation for string conversions, and it has special behaviour for primitives.
Number: Return NumberToString(argument).
Upvotes: 4
Reputation: 16557
JavaScript doesn't use toString
to convert primitive data types to string. It uses its own implementation. As a matter of fact, all these examples below follow your example:
let a = 1, b = 'string', c = false, d = 100.5, e = {}
a.__proto__.toString = _ => 'test'
b.__proto__.toString = _ => 'test'
c.__proto__.toString = _ => 'test'
d.__proto__.toString = _ => 'test'
e.__proto__.toString = _ => 'test'
console.log(a + 'X', b + 'X', c + 'X', d + 'X', e + 'X')
Upvotes: 1
Reputation: 2490
It's stored as a property of the prototype...
Remember that a number is a number. When you use it to be evaluated in an expression, such as with operator +, its toString method is not invoked. Instead, its value is resolved, and used to evaluate the rest of the expression.
Upvotes: -1