存储的数字字符串在哪里?

时间:2018-06-06 22:38:16

标签: javascript

例如,某些代码。

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}}或其他不可变类型在发生类型转换时存储和调用。

4 个答案:

答案 0 :(得分:28)

  

所以问题是在发生类型转换时存储和调用的toString of Number或其他不可变类型

它存储在Number.prototype上。更重要的问题是:

  

在执行1 + 'a'时,如何将数字转换为字符串?

不是通过toString方法!

toString方法仅在将对象转换为原始值时使用。但是,一个数字已经是一个原始值。相反,有一个内部 ToString例程被调用以将数字转换为字符串。详细信息可在12.8.37.7.127.1.12.1的ES2017规范中找到。细节有点长,但它是这样开始的:

  
      
  1. 如果mNaN,请返回字符串"NaN"
  2.   
  3. 如果m+0-0,请返回字符串"0"
  4.   
  5. ...
  6.   

如您所见,这些是关于如何将数字值转换为字符串的非常具体的说明,这与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方法。相反,它的值被解析,并用于评估表达式的其余部分。