看破 JavaScript 底层——实现 `a == 1`、`2`、`3`
2024-02-12 01:12:48
许多人可能一开始会觉得 a == 1
、a == 2
和 a == 3
的结果是 true
,但事实上,结果是 false
!在深入了解这个现象之前,我们必须清楚地认识到,value = 1
只是 a
的一个属性,并不等于 a
本身。
让我们再看一段代码:
const a = {
value: 1,
valueOf() {
return 2;
},
};
console.log(a == 1); // false
console.log(a == 2); // true
console.log(a == 3); // false
为什么在添加 valueOf()
方法后,a == 2
的结果就变成了 true
了呢?要理解这个问题,我们需要了解 ==
运算符背后的核心原理。
当我们使用 ==
运算符对两个值进行比较时,JavaScript 首先会尝试将这两个值转换为相同的类型,然后进行比较。如果这两个值是原始类型(如数字、字符串或布尔值),则直接进行比较。但是,如果这两个值都是对象,则会调用对象的 valueOf()
方法,将对象转换为原始类型后进行比较。
在上面的代码中,a
是一个对象,因此在比较 a == 1
、a == 2
和 a == 3
时,JavaScript 会先调用 a.valueOf()
方法将 a
转换为原始类型,然后再进行比较。由于 a.valueOf()
方法返回 2,因此 a == 2
的结果为 true
,而 a == 1
和 a == 3
的结果为 false
。
const a = {
value: 1,
toString() {
return '2';
},
};
console.log(a == 1); // false
console.log(a == 2); // true
console.log(a == 3); // false
除此之外,我们还可以使用 toString()
方法来修改对象的默认字符串表示,从而影响 ==
运算符的比较结果。
const a = {
value: 1,
valueOf() {
return 2;
},
toString() {
return '3';
},
};
console.log(a == 1); // false
console.log(a == 2); // false
console.log(a == 3); // true
在上面的代码中,我们重写了 a.toString()
方法,使其返回字符串 '3'。因此,当我们比较 a == 1
、a == 2
和 a == 3
时,JavaScript 会先调用 a.valueOf()
方法将 a
转换为原始类型 2,然后调用 a.toString()
方法将 2 转换为字符串 '2',再与 1、2 和 3 进行比较。由于 '2' 与 '3' 相等,因此 a == 3
的结果为 true
,而 a == 1
和 a == 2
的结果为 false
。