js基础:比较运算符隐式转换

隐式转换

  1. 运算符在运算的时候,如果两边的数据类型不一致,则会自动转成一致后运算。

    a. 其他类型转string :  + 连接符
    b. 其他类型转number :  
    	自增自减(++ --)
    	算术运算符( + - * / %)
    	关系运算符 :  > >= < <= == != === !==
    c. 其他类型转boolean :  ! 逻辑非
    
  2. 特殊情况

    === : 全等运算符。 不存在类型转换, 先比较类型,然后比较值
    ==  :  比较运算符。 隐式转换规则是转成number,但是有前提条件
    
  3. x == y: 比较运算符分为五种情况

    3.1 x和y 都为 null或undefined
          * 不会类型转换,得到固定值true
    3.2 x或y 为NaN 
          * 不会类型转换,得到固定值false  (NaN与任何数据都不等,包含自身)
    3.3 x和y 都为 string,boolean,number ,且类型不一致
          * 会类型转换, 会把其他类型转成number后计算
    3.4 x或y 为引用类型 (一个是引用类型,一个是值类型)
          * 前提 : 引用类型会先调用valueOf(),然后调用toString(),再来计算  (最终变成字符串来比较)
          * valueOf() : 一般引用类型,返回自身(一般忽略)
          * toString() : 数组是join()字符串, 对象是固定字符串 '[object Object]'
    3.5 x和y 都为引用类型。 则会比较两者地址,地址一样则为true,否则为false
    

全等运算符 === (不存在类型转换)

		// 严格匹配 : 数据类型 与 值 必须要同时相等
        console.log('1' === 1 );//false
        console.log( 1 === 1 );//true
        console.log( undefined === null );//false

比较运算符 : 隐式转换是有前提条件的 ( x == y )

		//2.1  x和y  都为 null或者undefined。 
        // 不会类型转换,固定返回true
        console.log( Number(null) );//0
        console.log( Number(undefined) );//NaN
        
        console.log( null == null );//true
        console.log( undefined == undefined );//true
        console.log( null == undefined );//true
        
        //2.2 x或y  为NaN 
        // 不会类型转换,固定返回false (NaN与任何数据都不等)
        console.log( NaN == 0 );//false
        console.log( NaN == undefined );//false
        console.log( NaN == null );//false
        console.log( NaN == NaN );//false
        
        //2.3 当x或y 都为 :string,number,boolean。 且数据类型不一致,此时会转换成number后运算
        console.log( 1 == '1' );//true   1 == Number('1')
        console.log( false == '0' );//true   Number(false) == Number('0')  0 == 0
        
        //2.4 x或y 存在引用类型,则会转成 `原始值` 后比较
        //  一个是引用类型,一个是基本类型
        // 引用类型转原始值 : 先调用对象的valueOf() 方法获取原始值,然后调用toString() 转成字符串比较
        // a :  valueOf() : 可以忽略, 对象类型默认valueOf会返回自身
        console.log( [10,20,30].valueOf() );// [10,20,30]
        console.log( new Number(10) );//10  valueOf() 默认只会对基本包装类型有效

        // b1.   toString() :  数组的toString() 本质是调用join()转成字符串
        console.log( [10,20,30] == '10,20,30' );//true
        console.log( [] == '' );//true
        console.log( [] == 0 );//true  (1) [].toString  (2) '' == 0 (3) 0 == 0
        // b2.   toString() :  对象的toString() 返回固定格式字符串  '[object Object]'
        console.log( {name:'张三'} == '[object Object]');//true
        console.log( {name:'李四'} == '[object Object]');//true
        

面试题

		/* 以下是针对第四种情况的面试题的坑(入门级) */
        console.log( [] == '' );//true
        console.log( [] == '[object Object]' );//false
        console.log( [] == 0 );//true

        console.log( {} == '' );//false
        console.log( {} == '[object Object]' );//true
        console.log( {} == 0 );//false

        /* 以下是针对第四种情况的面试题的坑(高手级) */
        console.log( [] == 0 );//true
        //(1)  ![] 隐式规则转布尔类型  !Boolean([]) =  !true = false
        //(2)  flase == 0
        //(3)  Number(false) == 0   0 == 0
        console.log( ![] == 0 );//true  
        console.log( {} == 0 );//false    '[object Object]' == 0
        console.log( !{} == 0 );//true   原理同  ![] == 0   不存在调用toString() 本质是逻辑非表达式结果 与 0 比较
        
        //2.5 x或y  都为引用类型。则直接比较两者地址,地址一致则为true,地址不一致则为false

        /* 以下为第五种情况面试题的坑(入门级) */
        var arr1 = [10,20,30];
        var arr2 = arr1;//拷贝地址 赋值
        var arr3 = [10,20,30];
        //虽然arr1 arr2 arr3打印的时候,一模一样的。但是他们对应的堆地址不同(钱一样银行卡不一样 )
        console.log(arr1 == arr2);//true
        console.log(arr1 == arr3);//false
        console.log(arr2 == arr3);//false

        /* 以下为第五种情况面试题的坑(高手级) */
        console.log( [] == [] );//false   声明两个空数组,堆中地址不同
        //(1)左边   ![] = !true = false
        //(2)右边   [].toString = ''
        //(3)false (数字0) == ''(数字0)
        console.log( ![] == [] );//true   
        console.log( ![] == ![] );//true  两个逻辑非表达式比较  !true == !true   false == false

        //原理同上
        console.log(  {} ==  {} );//false
        //(1)左边 !{} = !true = false
        //(2)右边 {}.toString = '[object Object]'
        //(3) false (数字0) == '[object Object]' (数字NaN)
        console.log( !{} ==  {} );//false  
        console.log( !{} == !{} );//true

        //以下为特殊情况
        // null是原型链终点, 底层是堆地址起点 0x0000
        console.log( null == 0);//false   null不会转换 ,会直接用地址 和 0 比较
        //以上五种情况 只是对 == 运算符生效。 其他的比较运算符还是转number
        console.log( null >= 0);//true  Number(null) >= 0   0 >= 0
        console.log( null <= 0);//true  Number(null) <= 0   0 <= 0

你可能感兴趣的:(js基础:比较运算符隐式转换)