为什么修改Number.prototype.toString不起作用?

时间:2017-04-06 17:43:15

标签: javascript

在javascript中,使用添加符号(+)来连接字符串和 另一个变量,如果变量不是distinctUntilChanged,该变量将隐式调用其toString方法。为了验证这一点,我做了一个名为Apple的构造函数。

string

它按我的预期工作:在计算function Apple(name) { this.name = name; } Apple.prototype.toString = function() { console.log('Apple.prototype.toString called.'); return this.name; }; var apple = new Apple('Thai apple'); var msg = apple + ' tastes good.' console.log(msg) 时, 调用apple + ' tastes good'。 然后我在Apple.prototype.toString类型上进行了类似的实验。

Number

运行之后,我注意到Number.prototype.num2str = Number.prototype.toString; Number.prototype.toString = function() { console.log('new Number.prototype.toString called.'); return this.num2str(); } var msg = 'num = ' + 123; console.log(msg); 没有被调用。 我很困惑。为什么它不像前面的例子一样工作?

1 个答案:

答案 0 :(得分:4)

  

为什么它不像前面的例子一样工作?

仅当值为对象时才会调用

toString(但请参见下文)。 123不是对象,它是原语(数字)值。将原始值转换为字符串值遵循不同的规则。请参阅ES2016规范中的§7.1.12§7.1.12.1具体数字(此处引用的时间太长),了解如何将值转换为字符串。

当使用+运算符时,原始值强制转换为对象。

但是,即使您创建了一个数字对象,它也无法正常工作。这是因为toString实际上并没有为数字对象调用。那是为什么?

When performing additio n,执行以下步骤:

  

[...]
  5.让 lprim 成为? ToPrimitive( lval中)。
  6.让 rprim 成为? ToPrimitive( RVAL )。
  [...]

两个值在之前首先转换为原始值它们被特定地转换为数字或字符串(原始值可以是字符串,数字,布尔值,null或{{ 1}})。
以这种方式将对象转换为原始值最终将首先调用undefined。仅当该函数的返回值时,原始值才会调用valueOf

由于toString返回原始值,因此不会调用new Number(123).valueOf()

以下是针对toString调整的示例:



valueOf




NB: Number.prototype.valueOf = function() { console.log('new Number.prototype.valueOf called.'); return 'something'; } var msg = 'num = ' + new Number(123); console.log(msg);toString实际上是将对象转换为字符串/数字/基元的过时方式。从ES6开始,新的是调用对象的valueOf方法。只有在不存在的情况下,才会调用@@toPrimitvetoString(请参阅§7.1.1 ToPrimitive)。