下面我们来详细分析一段有趣的代码

var obj = {
        a:1,
        [Symbol.toPrimitive]:function () {
           console.log(1);
           return 1;
        },
        valueOf(){
            console.log(2);
            return {};
        },
        toString(){
            console.log(3);
            return 3;
        }
    }
    console.log(obj+3)

以下是对这段 JavaScript 代码的详细解释:

var obj = {
    a: 1,
    [Symbol.toPrimitive]: function () {
        console.log(1);
        return 1;
    },
    valueOf(){
        console.log(2);
        return {};
    },
    toString(){
        console.log(3);
        return 3;
    }
}
console.log(obj + 3)

首先,我们定义了一个名为 obj 的对象。

  • a: 1 是对象的一个属性,其键为 a,值为 1
  • [Symbol.toPrimitive] 是一个特殊的属性,它定义了对象在需要转换为原始值时的行为。这里的函数会先打印 1,然后返回 1
  • valueOf 方法通常用于尝试将对象转换为原始值。在这个例子中,它打印 2 但返回一个非原始值的对象 {}
  • toString 方法也是用于对象到字符串的转换。这里打印 3 并返回数字 3

当我们执行 console.log(obj + 3) 时,JavaScript 会尝试将 obj 转换为原始值以便进行加法运算。

由于存在 [Symbol.toPrimitive] 方法,并且它具有最高优先级,所以会先调用这个方法。按照其定义,先打印 1 ,然后将其返回的值 13 进行加法运算,最终输出结果 4

另一种情况

var obj = {
    a: 1,
    valueOf(){
        console.log(2);
        return {};
    },
    toString(){
        console.log(3);
        return 3;
    }
}
console.log(obj + 3)

首先,定义了一个名为 obj 的对象。
a: 1 是对象的一个属性,键为 a,值为 1 。
valueOf 方法用于尝试将对象转换为原始值。当 JavaScript 试图进行类型转换时会调用这个方法。这里它先打印 2 ,但返回的是一个非原始值的对象 {} 。
toString 方法用于将对象转换为字符串。这里它先打印 3 ,然后返回数字 3 。
当执行 console.log(obj + 3) 时,JavaScript 会尝试将 obj 转换为原始值以进行加法运算。
由于 valueOf 方法返回的不是原始值,所以会继续调用 toString 方法。因为 toString 方法返回了数字 3 ,所以最终的计算就是 3 + 3 ,结果为 6 。
例如,如果 toString 方法返回的是 5 ,那么最终的计算结果就是 5 + 3 = 8 。

Last modification:August 8, 2024
如果觉得我的文章对你有用,请随意赞赏