六种方法让(a==1&&a==2&&a==3)的值为true?

220 阅读1分钟

如果需要让a==1&&a==2&&a==3最后返回的值为true,使用==比较的时候存在数据转换,我们可以充分利用这个特点,让a发生数据转换。

本文主要思路:

  • 利用了数据拦截
  • 重写了对象和数组的转换为原始值需要使用的原型上的方法。

方法一 Object.definedProperty

拦截变量的获取

let num = 1;
Object.defineProperty(window, 'a', {
    get() {
        return num++;
    }
});
console.log(a == 1, a == 2, a == 2); // true true true

方法二 Reflect.definedProperty

拦截变量的获取

let num2 = 1;
Reflect.defineProperty(window, 'b', {
    get() {
        return num2++;
    }
})
console.log(b == 1, b == 2, b == 3); // true true true

方法三 [symbol.toPromitive]

拦截变量的获取

let f = {
    value: 1,
    [Symbol.toPrimitive]() {
        return this.value++;
    }
}
console.log(f == 1, f == 2, f == 3); // true true true

方法四 valueOf

对象转换为原始值时,会先调用valueOf方法,如果方法不存在或返回的值不是原始值,则会再去调用toString方法。

let d = {
    value: 1,
    valueOf() {
        return this.value++;
    }
}
console.log(d == 1, d == 2, d == 3);

方法五 toString

这个方法只适合在 == 的时候使用,利用对象在与原始值比较的时候,会隐式转换为原始值。

let c = {
    value: 1,
    toString() {
        return this.value++;
    }
}
console.log(c == 1, c == 2, c == 3); // true true true

方法六数组 + shift

数组。数组的toString:默认会调用join方法拼接每个元素并且返回拼接后的字符串

let e = [1, 2, 3];
e.join = e.shift;
console.log(e == 1, e == 2, e == 3);