例如,某些代码。
let a = 1
a.__proto__.toString = function(){ return 'test'}
a.toString()
//"test"
a + '2'
//"12"
我真的无法理解存储toString
方法的位置。
如果我用可变对象做到这一点我得到了
let o = {}
o.__proto__.toString = function(){ return 'test'}
o.toString()
//"test"
o + '2'
//"test2"
这就像我预期的那样有效。
所以问题是toString
的{{1}}或其他不可变类型在发生类型转换时存储和调用。
答案 0 :(得分:28)
所以问题是在发生类型转换时存储和调用的toString of Number或其他不可变类型
它存储在Number.prototype
上。更重要的问题是:
在执行
1 + 'a'
时,如何将数字转换为字符串?
不是通过toString
方法!
toString
方法仅在将对象转换为原始值时使用。但是,一个数字已经是一个原始值。相反,有一个内部 ToString
例程被调用以将数字转换为字符串。详细信息可在12.8.3,7.7.12和7.1.12.1的ES2017规范中找到。细节有点长,但它是这样开始的:
- 如果
m
为NaN
,请返回字符串"NaN"
。- 如果
m
为+0
或-0
,请返回字符串"0"
。- ...
醇>
如您所见,这些是关于如何将数字值转换为字符串的非常具体的说明,这与toString
上定义的实际Number.prototype.toString
方法无关。
答案 1 :(得分:4)
这里的问题不在于Number.prototype
;只是在将数字转换为字符串时不会调用Number.prototype.toString
。 JavaScript使用its internal ToString operation进行字符串转换,它对基元有特殊的行为。
Number:返回NumberToString(参数)。
答案 2 :(得分:1)
JavaScript不使用toString
将原始数据类型转换为字符串。它uses its own implementation。事实上,以下所有这些示例都遵循您的示例:
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')
答案 3 :(得分:-1)
它被存储为原型的属性......
请记住,数字是一个数字。当您在表达式中使用它进行计算时,例如使用operator +,不会调用其toString方法。相反,它的值被解析,并用于评估表达式的其余部分。