怎么让 a == 1 && a==2 && a==3 的结果为 true?

让 a == 1 && a==2 && a==3 的结果为 true

阅读 3.6k
3 个回答
function A() {
    this.value = 0;
    this.toString = function() {
        return ++this.value
    }
}
const a = new A();

a == 1 && a == 2 && a == 3

相等运算符 ==!= 使用 抽象相等比较算法 比较两个操作数。可以大致概括如下:

  • 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回 true
  • 如果一个操作数是 null,另一个操作数是 undefined,则返回true
  • 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型:

    • 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
    • 如果操作数之一是 Boolean,则将布尔操作数转换为1或0。

      • 如果是 true,则转换为 1
      • 如果是 false,则转换为 0
    • 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的 valueOf()toString() 方法将对象转换为原始值。
  • 如果操作数具有相同的类型,则将它们进行如下比较:

    • Stringtrue 仅当两个操作数具有相同顺序的相同字符时才返回。
    • Numbertrue 仅当两个操作数具有相同的值时才返回。+0 并被 -0 视为相同的值。如果任一操作数为 NaN,则返回 false
    • Booleantrue 仅当操作数为两个 true 或两个 false 时才返回 true

来自 https://developer.mozilla.org...

这不是答案,只是补充

使用 valueOftoString 可达到目的。单个重载实现的情况下,隐藏转换调用都比较明确。但如果两个都实现了,隐式转换的时候到底该调哪个?

  • 比如 a == 1 的时候是用 valueOf() 还是 toString() 来转换的?
  • 那么 a == "1" 的时候呢?
  • a + "1" 呢?又或者 "1" + a

直觉除了 a == 1 使用 valueOf() 之外,都应该使用 toString(),但实测全是使用的 valueOf() —— 说实在的,我很迷茫。

不过还有一个 Symbol.toPrimitive,在隐式转换的时候优先级比前二者更高,比如

class A {
    value = 0;
    [Symbol.toPrimitive](hint) {
        console.log(hint);
        switch (hint) {
            case "string":
                return this.value;
            // case "number":
            // case "default":
            default:
                return ++this.value;
        }
    }
}

其实可以达到同样的效果,而且 console.log(hint) 输出都是 default。同样不是很清楚在什么时候 hint 会是 "string", "number", "default" 中的哪一个。但是实测在 ${a} 124 的时候 hint 是 "string",在 ~~a 的时候 hint 是 "number"

  let value = 1
  Object.defineProperty(window, `a`, { 
      get() {
          return value++
      }
  })
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题