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

标签 javascript

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

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);

运行后,我注意到 Number.prototype.toString 没有被调用。 我很困惑。为什么它不像前面的示例那样工作?

最佳答案

Why doesn't it work like the previous example?

toString 仅在值为对象 时调用(但请参阅下文)。 123 不是一个对象,它是一个原始(数字)值。将原始值转换为字符串值遵循不同的规则。参见 §7.1.12在 ES2016 规范中,和 §7.1.12.1特别是关于如何将值转换为字符串的数字(此处引用太长)。

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


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

When performing additio n,发生以下步骤:

[...]
5. Let lprim be ? ToPrimitive(lval).
6. Let rprim be ? ToPrimitive(rval).
[...]

这两个值首先被转换为原始值之前它们被转换为数字或字符串(原始值可以是字符串、数字、 bool 值、nullundefined)。
以这种方式将对象 转换为原始值最终将首先调用valueOf。仅当该函数的返回值不是原始值时才会调用toString

因为 new Number(123).valueOf() 返回原始值,所以 toString 不会被调用!

这是针对 valueOf 调整的示例:

Number.prototype.valueOf = function() {
  console.log('new Number.prototype.valueOf called.');
  return 'something';
}

var msg = 'num = ' + new Number(123);
console.log(msg);


NB: toStringvalueOf 实际上是将对象转换为字符串/数字/基元的过时方法。从ES6开始,新的是调用对象的@@toPrimitve方法。只有当它不存在时,才会调用 toStringvalueOf(请参阅 §7.1.1 ToPrimitive)。

关于javascript - 为什么修改 Number.prototype.toString 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43262266/

相关文章:

javascript - 使用 jQuery 收集元素类数组

javascript - 不能使用从 promise 解析和返回的值

javascript - 动画形式,如何检查页面刷新时的输入值?

javascript - 使用 Node js ('nw.gui' 将对象传递给其他窗口)

javascript - 为什么 JavaScript 对 plus 和 string 和 int 的计算方式不同?

javascript - AngularJS - 使用多种形式

javascript - 包裹的可点击 DivElement : event isn't listened

javascript - AngularJS,仅在变量为真时过滤

javascript - 使用 JSON.stringify 转换关联数组的问题

javascript - 如何用外部文件替换一些内联 JavaScript 事件处理程序?