在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);
没有被调用。
我很困惑。为什么它不像前面的例子一样工作?
答案 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
方法。只有在不存在的情况下,才会调用@@toPrimitve
或toString
(请参阅§7.1.1 ToPrimitive
)。