美文网首页
在JS中,如何让(a===1 && a===2 && a ===

在JS中,如何让(a===1 && a===2 && a ===

作者: 習惯不曾習惯的習惯 | 来源:发表于2018-12-19 10:50 被阅读0次

      之前在社区看到这道题时,我第一反应就是如果我在代码库中看到这样的代码我肯定是很绝望的!!!言归正传,看到这题的时候,我首先想到的是(a == 1 && a == 2 && a==3)为true的情况(宽松匹配),我们先了解这种情况,然后在解决扩展问题。
      首先,在JS中,宽松匹配 ==会先将左右两两边的值转化成相同的原始类型,然后再去比较他们是否相等。在转化之后(== 一边或两边都需要转化),最后的相等匹配会像 ===符号一样去执行判断。
      那么,我们考虑到的应该是a应该是什么类型,在a==**的时候发生了什么?再去考虑a应该等于什么。

    1. 如果a是一个对象Object,那在执行a==的时候首先会去先执行valueOf方法,如果没有valueOf方法,就会去执行toString方法。(toString方法与valueOf类似,这里不再重复)
    const a = { value: 0 }
    a.valueOf = function () {
        return  this.value += 1
    }
    console.log( a == 1 && a == 2 && a == 3 );
    
    1. 如果a是一个数组Array,在数组转换成字符串的时候,数组toString会隐含调用join()方法
    const a = [1, 2, 3];
    a.join = a.shift;
    console.log( a == 1 && a == 2 && a ==3 );
    

      那么,(a === 1 && a === 2 && a === 3)的值也能是true吗?
    答案当然是肯定的!
      但是,严格相等并没有转化的过程,所以我们需要通过一些方式去调用一个函数,并在这个函数中做我们想做的事情。但是执行函数往往需要在函数名字后引入 () ,并且由于这里不是宽松相等 ==valueOf将不会被JS引擎调用。幸好Object提供了一个Property函数, 特别是getter描述符, 带来了解决这个问题的办法。

    var value = 0; //window.value
    Object.defineProperty(window, "a", {
        get: function () {
            return  this.value += 1
        }
    })
    console.log( a === 1 && a === 2 && a === 3 );
    

      上面代码中,我们在window对象上定义了一个具有getter的 a 属性, 通过get属性, 我们可以调用一个函数并且不用在函数名后添加 (),所以 a 可以在代码中直接被访问到(全局变量), 因此也可以直接获得a的值。如果我们在其他对象上定义了属性 a 而不是window的话,例如object1, 我们就需要改变题目为 object1.a === 1 && object1.a === 2 && object1.a === 3 了。
      扩展:字符编码实现相同效果

    var aᅠ = 1;
    var a = 2;
    var ᅠa = 3;
    console.log(aᅠ === 1 && a === 2 && ᅠa=== 3 );
    

    相关文章

      网友评论

          本文标题:在JS中,如何让(a===1 && a===2 && a ===

          本文链接:https://www.haomeiwen.com/subject/qzddkqtx.html