gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 09:36:29 25 4
gpt4 key购买 nike

在 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com