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

56 阅读1分钟

如果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