js对象转换为原始类型出现的问题

在将对象转换为原始类型时有点不太懂

    let obj = {
        a: 'aaa',
        valueOf() {
            return 'valueOf';
        },
        toString() {
            return 'toString';
        }
    };
    
    console.log('' + obj); // valueOf
    console.log(String(obj)); // toString

请问大佬们, 这两种转换obj的方式有什么不同吗?

阅读 2.5k
2 个回答

javascript +运算符 执行算法

  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be ? GetValue(lref).
  3. Let rref be the result of evaluating MultiplicativeExpression.
  4. Let rval be ? GetValue(rref).
  5. Let lprim be ? ToPrimitive(lval).
  6. Let rprim be ? ToPrimitive(rval).
  7. If Type(lprim) is String or Type(rprim) is String, then
    a. Let lstr be ? ToString(lprim).
    b. Let rstr be ? ToString(rprim).
    c. Return the string-concatenation of lstr and rstr.
  8. Let lnum be ? ToNumber(lprim).
  9. Let rnum be ? ToNumber(rprim).
  10. Return the result of applying the addition operation to lnum and rnum. See the Note below 12.8.5.

可以看到,在进行加法运算的时候,首先(步骤 5,6)要把运算符都转换为基本类型。

之后,如果(转换基本类型的结果中)一方是 string 的话,双方转换为 string (步骤7.a 7.b)。

在转换为基本类型的时候(步骤 5,6),除了 Date ,基本都是先尝试 valueOf ,在尝试 toString 的。

============
来自评论:

那就还有个问题啦 let obj = {a: '1'}; 此时调用obj的valueOf返回的是{a: '1'}这样的字符串, 但是在做 '' + obj的时候又返回[object Object], 请问这是说明在执行此相加时调用valueOf方法尝试将obj转换为原始值时并没有返回因此调用了toString方法吗?

先看:

调用obj的valueOf返回的是{a: '1'}这样的字符串

这里 valueOf 的返回不是字符串,而是通常是这个对象本身。它只执行了一个简单的操作:Return ToObject(this)。这个对象本身打印出来的时候,可能像是一个字符串,但并不是。

对于一般的对象,ToPrimitive 会使用 OrdinaryToPrimitive(O, hint),其中 hint 是 number :

  1. Assert: Type(O) is Object.
  2. Assert: Type(hint) is String and its value is either "string" or "number".
  3. If hint is "string", then
    a. Let methodNames be « "toString", "valueOf" ».
  4. Else,
    a. Let methodNames be « "valueOf", "toString" ».
  5. For each name in methodNames in List order, do
    a. Let method be ? Get(O, name).
    b. If IsCallable(method) is true, then

    i. Let result be ? Call(method, O).
    ii. If Type(result) is not Object, return result.
  6. Throw a TypeError exception.

这个操作是用于转换为基本类型的,因而在 5.b.ii ,如果 valueOf 或 toString 返回的结果是一个 object ,那么就不会使用这个结果,而是继续尝试下一个。对普通 object ,转换为基本类型时,不会使用 valueOf 的结果(因为他是一个 object),而是会继续尝试 toString 。

隐形转数字,用valueOf;转字符串用toString。应该是这样

推荐问题