当方法 valueOf 可能不存在时? Return types

问题描述

我有这个代码。我不明白它是如何工作的。

let obj = {
    valueOf: function () {
        return {};
    },toString: function () {
        return 222;
    }
};

console.log(Number(obj)); //222

根据这个source,转换算法为:

  1. 如果方法存在,则调用 obj[Symbol.toPrimitive](hint)
  2. 否则,如果提示是“字符串”,请尝试 obj.toString()obj.valueOf(),无论存在什么。
  3. 否则,如果提示是“数字”或“认”,请尝试 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


唯一强制性的事情:这些方法必须返回一个原语,而不是 一个对象。

历史记录
由于历史原因,如果 toStringvalueOf 返回一个对象, 没有错误,但是这样的值会被忽略(就像如果方法没有 存在)。

在您的第一个代码段中,两种方法都存在并且尝试:第一个 obj.valueOf(),但由于它返回一个空对象而不是原始值,{{ 1}} 也被调用。

在您的第二个代码段中,obj.toString() 已经返回数字 obj.valueOf(),它成为结果。