返回

看破 JavaScript 底层——实现 `a == 1`、`2`、`3`

前端

许多人可能一开始会觉得 a == 1a == 2a == 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 == 1a == 2a == 3 时,JavaScript 会先调用 a.valueOf() 方法将 a 转换为原始类型,然后再进行比较。由于 a.valueOf() 方法返回 2,因此 a == 2 的结果为 true,而 a == 1a == 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 == 1a == 2a == 3 时,JavaScript 会先调用 a.valueOf() 方法将 a 转换为原始类型 2,然后调用 a.toString() 方法将 2 转换为字符串 '2',再与 1、2 和 3 进行比较。由于 '2' 与 '3' 相等,因此 a == 3 的结果为 true,而 a == 1a == 2 的结果为 false