美文网首页
js'==' 判断相等时类型强转规则

js'==' 判断相等时类型强转规则

作者: zevolv | 来源:发表于2019-01-25 18:06 被阅读0次

    简单介绍一下 '==' ,毕竟这也是js中常见的坑,如果有问题欢迎大家指正,

    [TOC]

    相同类型的 '=='

    总的来说,相同类型的 == 和 === 是一样的。

    类型相同的基础类型

    这个就很直接了,对于基础类型直接就是干,一样就相等,不一样就不等,Symbol和NaN是特例,Symbol是因为自己的特性,NaN,not a Number(翻译过来就是说这玩意不是数字,在数字上面表示的NaN就没啥意义)

        var a = 1,b = 2;
        console.log(a == b);
        a = false,b = true;
        console.log(a == b);
        a = "123",b = "123";
        console.log(a == b);
    
        console.log(NaN == NaN)   ;//false 
        
    

    类型相同的Object类型

    //这个其实也是有点意思的,得从js变量说起,js的变量在我的理解下和c语言的引用是一样的。
    //这个Object之间的 == 说实话也是和基础类型一样,只是不那么直观,看如下代码
    var a = {}, b = {}
    console.log(a == b)
    b = a;
    console.log(a == b)
    
    //大概通俗易懂的就是,有明显的 b = a 或者 a = b 之后对象 的 == 才会是true
    // 从引用层面来说,就是a 指向的地址和 b 指向的地址相同,其实基础变量也可以理解为这样判断的
    

    相同类型的判断就大概如上,很直接

    不同类型的 '==' 判断

    这个就有点意思了,知乎上有个大神画了张图,感觉很厉害,这里就不搬下来了

    null 和 undefined

    这俩和其他类型比较都是false,但是互相比较就是true

        console.log(undefined == null);//true
        console.log(null == undefined);//true
    

    基础类型的比较 Number,Boolean,String,都是转为Number 的

    强转规则参照

    Boolean

    Boolean 只能转 0 或者 1
    所以Boolean 和其他值的比较大概就是,数字 0 和 1 和其他类型进行比较

        console.log(false == 0);//true
        console.log(false == '0');//true
        console.log(false == '');//true
        console.log(true == 1);//true
        console.log(true == '1');//true
    

    Number

    Number 啥也不用干,就放在那里作为被比较的对象
    强转规则参照

        
        console.log(Infinity == 1/0);//true
        console.log(-Infinity == -1/0);//true
    
    
        console.log(false == 0);//true
        console.log(true == 1);//true
        console.log(1 == '1');//true
        console.log(0 == '');//true
        console.log(0 == []);//true
    
        //NaN 是个有点意思的
        console.log(NaN == NaN);//false
        console.log(NaN == !NaN);//false
    
    

    String

    遇到Boolean和Number时 转Number ,其他也没啥了哈
    强转规则参照

    //Boolean
        console.log(false == '0');//true
        console.log(false == '');//true
        console.log(true == '1');//true
        console.log(false == 'false');//'false' 这个是烟雾弹,‘false’是有字符的,参照基础变量的强转,就转为NaN了
    
        console.log(255 == '0xFF');//true
        console.log(255 == '0255');//true
        console.log(-Infinity == '-Infinity');//true
        console.log(Infinity == 'Infinity');//true
        
    

    Object 这个玩意非常有意思

    就是一个转换,调用Primitive方法实现的,具体是调用Object的valueOf,如果valueOf返回的是对象,则调用toString,否则就直接用valueOf返回的值。

    上面这段话要仔细品味呀,有点意思的
    有些东西需要多实践的 ,敲敲代码运行代码感受下js设计者的心思

            var a = {}
            a.toString = function(){ return '2'};
            a.valueOf = function(){return 1}
            console.log(a == 1,a=='2');//true ,false
            var c = {};
            c.toString = function(){ return 'c'};
            a.valueOf = function(){return c}
            console.log(a == 'c');//false
    
            console.log({} == '[object Object]')
            
    
    
    

    取反操作,很骚

    为什么取反操作就骚起来了呢,主要是对于取反操作来说,所有的其他类型都会转为Boolean类型,转换规则是null,undefined,0,-0,NaN,空字符串(“”)为false,其他全为true,所以取反操作就很容易做一些坑,比如![] , !+[]



    补充一个小知识,Array.prototype.toString 返回的值很有意思的,有很多人那这个来玩,说白了就是利用js的各种强转和运算符优先级来搞事情,不是什么值得骄傲的事。

    运算符优先级 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

        var a = ['a',['b',['c'],'d'],'e']
        console.log(a == 'a,b,c,d,e');//true
        //暂时没看源码,但是大概可以理解为 
        //数组的toString 相当于每一项调用toString之后再 调用join(',')
        //所以看下面的
        console.log([] == 0);//true
        console.log([[['0']]] == 0);//true
    
    
        console.log([] == ![]);//true  -- ![] 为bool值,转number 为 0 ,[] toString 为 ‘’ 转number 为 0
        console.log([] == []);//false  --同类型,都是Object,引用地址不一样
    
    
        //这段代码的解析看下面
        console.log((![] + [])[ -~!+[]+!+[] ]+({}+[])[-~!+[]] )
        //解析一段小代码 ![] + [] -》 []为Object且不为空 ,所以![] 为false, false + [] ,不同类型,[] 调用toString() 即得false字符串,
        // 按照运算符优先级,~ 和 !高于 +-,但是逻辑操作从右到左,即+[] 会作为左边第一个!的对象,+[]即把[]转为数字0, 即-~!(+[]) -->   -~!(0)   —->   -~(true)    -->     -~(1)       -->   -(-2)     -->  2
        //所以 2 + !+[] = 3 和上面一样 +[]为0 , +!0 = +1,
        // 即得 (‘false’)[3]   -->   s
        //同理 {} + [] 对象相加,调用其toString , 普通对象的tostring 返回的是 [object Object] ,数组的toString上面有说,所以这里返回的是“” 即得字符串 ‘[object Object]’
        
        // -~!+[] 逻辑操作从右到左,优先级高于 +-*/ 所以我们优先看!+[] -> 1 取反得-2 再取相反数得 2
    
        // 即得(‘[object Object]’)[2]  ---> b 
    
        // 与上面的操作连接起来,这也就是那些所谓的js 装x来骂人的词了。
        
    

    相关文章

      网友评论

          本文标题:js'==' 判断相等时类型强转规则

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