问题描述
let obj = {
valueOf: function () {
return {};
},toString: function () {
return 222;
}
};
console.log(Number(obj)); //222
根据这个source,转换算法为:
- 如果方法存在,则调用
obj[Symbol.toPrimitive](hint)
, - 否则,如果提示是“字符串”,请尝试
obj.toString()
和obj.valueOf()
,无论存在什么。 - 否则,如果提示是“数字”或“默认”,请尝试
obj.valueOf()
和obj.toString()
,无论存在什么。
这里的提示是数字。那为什么叫 obj.toString()
呢?没有obj.valueOf()
吗?为什么?什么样的对象有这个方法?我找不到任何关于此的有用信息。
这是另一个例子:
var room = {
number: 777,valueOf: function() { return this.number; },toString: function() { return 255; }
};
console.log( +room ); // 777
为什么在这种情况下调用 obj.valueOf()
?为什么这个方法在这里存在,而在第一个例子中没有?它是如何工作的?
解决方法
来自您引用的文章:
Return types
…
唯一强制性的事情:这些方法必须返回一个原语,而不是
一个对象。
历史记录
由于历史原因,如果 toString
或 valueOf
返回一个对象,
没有错误,但是这样的值会被忽略(就像如果方法没有
存在)。
在您的第一个代码段中,两种方法都存在并且尝试:第一个 obj.valueOf()
,但由于它返回一个空对象而不是原始值,{{ 1}} 也被调用。
在您的第二个代码段中,obj.toString()
已经返回数字 obj.valueOf()
,它成为结果。