a == 1&&a == 2&&a == 3 与 a === 1&&a === 2&&a === 3解法汇总

480 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。
最近在掘金刷到一篇名为如何实现a===1&&a===2&&a===3的文章,咋一看,下意识就想:嘿!想考我?还好之前有个沙雕群友在群里发过,解题思路我还记得[笑容逐渐猖狂.gif],主要是通过触发Object的toString()然后每次调用返回值自增达到三次触发toString()得到三个不同的值。
群友的聊天记录:WechatIMG562.jpeg 那么,根据这个就可以得到

    let a = {
        value:1,
        toString() {
            return this.i++
        }
    }
    console.log(a===1&&a===2&&a===3)

结果:

1641027184930.jpg

看到控制台输出的我:???

heli.jpeg

buheli.jpg

于是我改了下代码再来:

1641027184931.jpg

也就是说通过Object的toString()可以实现a == 1 && a == 2 && a == 3 而并不能实现a === 1&&a === 2 && a === 3

我想了下静静之后···过段的加上了万能的console

1641028426462.jpg

也就是说问题出在=====之间的差别,类型比较?也就是说使用==隐式转换使得Object调用了toSting(),emmmmm...

hengheli.jpg

到了这里,我开始继续看如何实现a===1&&a===2&&a===3,看完之后我产生了收集使a == 1&&a == 2&&a == 3为true使a === 1&&a === 2&&a === 3为true的方法各有几种的念头,于是在网上搜索相关的方法,整理如下。

使a == 1&&a == 2&&a == 3为true的方法

    // 方法1:通过toString()实现
    let a = {
        i:1,
        toString(){
            return this.i++
        }
    }
    console.log(a == 1&&a == 2&&a == 3) // true
    
    // 方法2:通过valueOf()实现
    let b = {
        i:1,
        valueOf(){
            return this.i++
        }
    }
    console.log(b == 1&&b == 2&&b == 3) // true
     
     // 方法3:Object.defineProperty实现
    let value = 1;
    Object.defineProperty(window, "c", {
      get:function() {
        return value++;
      }
    });
     console.log(c == 1 && c == 2 && c == 3) // true
     
     // 方法4:Proxy实现
     let d = new Proxy(
      {},
      {
        value: 1,
        get(target, key) {
          return () => this.value++;
        },
      }
    );
    console.log(d == 1 && d == 2 && d == 3) // true
    
    // 方法5:Symbol.toPrimitive实现
    let e = {
      value: 1,
      [Symbol.toPrimitive]: () => {
        return e.value++;
      },
    };
    console.log(e == 1 && e == 2 && e == 3) // true
    
    // 方法6:数组的shift()实现
    let f = [1, 2, 3];
    f.join = f.shift;
    console.log(f == 1 && f == 2 && f == 3) // true
    
    // 方法7:数组的pop()实现
    let g = [3, 2, 1];
    g.join = g.pop;
    console.log(g == 1 && g == 2 && g == 3) // true

使a === 1&&a === 2&&a === 3为true的方法

    // 方法1:Object.defineProperty实现
   let value = 1;
   Object.defineProperty(window, "a", {
     get:function() {
       return value++;
     }
   });
    console.log(a === 1 && a === 2 && a === 3) // true
    
    // 方法2:Proxy实现
    // 这有别的问题没搞懂,标记下
   let b = {
       number1
   };
   b = new Proxy(b, {
       get(target, key) {
           return target[key]++;
       }
   });
   console.log(b.number === 1 && b.number ===2 && b.number ===3) // true

刚开始觉得整理好这些方案以后面试遇到了就可以用孔乙己的口吻跟面试官说:(a == 1&&a == 2&&a == 3) == true有7中方法你知道吗? 现在我只想说JS有毒!快逃!!

参考文章