下面我们来详细分析一段有趣的代码
代码语言: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)
以下是对这段 JavaScript 代码的详细解释:
代码语言: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
,然后将其返回的值 1
与 3
进行加法运算,最终输出结果 4
。
另一种情况
代码语言:javascript复制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 。