如何让 (a == 1 && a == 2 && a == 3) 成立

175 阅读1分钟

前言

前几天在网上看到了一道很有趣的面试题,内容为:如何让 a == 1 && a == 2 && a == 3 这个表达式返回 true ?

这个表达式似乎不太可能返回true,因为在正常情况下,一个变量的值如果没有手动修改,在一个表达式中是不会变化的。

让这个表达式成为 true 的关键就在于这里的宽松相等,在处理宽松相等时会对一些变量进行隐式转换。在这种隐式转换的作用下,真的可以让一个变量在一个表达式中变成不同的值。

1.toString()

const a = {
  i1,
  toStringfunction () {
    return a.i++;
  }
}
console.log(a == 1 && a == 2 && a == 3) // true

2.valueOf()

const a = {
    i: 0,
    valueOf() {
      return ++this.i
    }
}
console.log(a == 1 && a == 2 && a == 3) // true

3.ES6中的Proxy

var a = new Proxy({ i: 1 }, {
    get(target) { return () => target.i++ }
});
console.log(a == 1 && a == 2 && a == 3) //true

如果是严格相等即(a === 1 && a === 2 && a === 3)上述三种方法就不可以了,

这时候需要用到ES5的defineProperty方法来实现

//浏览器环境中
var i = 1
Object.defineProperty(window, 'a', {
  get() { return i++ }
})
console.log(a === 1 && a === 2 && a === 3) //true

//nodejs
const value = function* () {
    let i = 1
    while(true) yield i++
}()
  
Object.defineProperty(global, 'a', {
    get() {
      return value.next().value
    }
})
console.log(a === 1 && a === 2 && a === 3) //true