如果a是一个对象,那在执行a==的时候首先会去先执行valueOf方法,如果没有value方法,就会去执行toString方法。因此我们可以改写a对象的valueOf和toString方法:
1. 1.1改写对象的valueOf
let a = {
valueOf: (function() {
let i = 1;
// 闭包,i不会被清除
return function() {
return i ++;
}
})()
}
console.log(a == 1 && a == 2 && a == 3) // true
1.2不用闭包
let a = {
i: 1,
valueOf: function() {
return this.i ++;
}
}
console.log(a == 1 && a == 2 && a == 3) // true
2.修改toString (同1.1)
let a = {
toString: (function() {
let i = 1;
// 闭包,i不会被清除
return function() {
return i ++;
}
})()
}
console.log(a == 1 && a == 2 && a == 3) // true
3.数组toString默认就是调用join方法,可以重新join
let a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3) // true
4.数据劫持实现
4.1 Object.defineProperty
let i = 1;
Object.defineProperty(window, 'a', {
get: function() {
return i ++;
}
})
console.log(a == 1 && a == 2 && a == 3) // true
4.2 proxy实现
let a = new Proxy({}, {
i: 1,
get: function() {
return () => this.i ++;
}
})
console.log(a == 1 && a == 2 && a == 3) // true