前言
前几天在网上看到了一道很有趣的面试题,内容为:如何让 a == 1 && a == 2 && a == 3 这个表达式返回 true ? 。
这个表达式似乎不太可能返回true,因为在正常情况下,一个变量的值如果没有手动修改,在一个表达式中是不会变化的。
让这个表达式成为 true 的关键就在于这里的宽松相等,在处理宽松相等时会对一些变量进行隐式转换。在这种隐式转换的作用下,真的可以让一个变量在一个表达式中变成不同的值。
1.toString()
const a = {
i: 1,
toString: function () {
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