js中比较运算符隐式类型转换

前言
相信大家在代码中经常看见 '==' 和 '===',但大家真的弄懂了比较运算符和其中的隐式转换嘛? 今天就重新认识下比较运算符。JavaScript 类型转换

全等运算符 ===

说明: 严格匹配,不会类型转换,必须要数据类型和值完全一致




先判断类型,如果类型不是同一类型的话直接为false;

1 对于基本数据类型(值类型): Number,String,Boolean,Null和Undefined:两边的值要一致,才相等
      console.log(null === null)   // true
      console.log(undefined === undefined)  // true
   注意: NaN: 不会等于任何数,包括它自己
   console.log(NaN === NaN)  // false 

2 对于复杂数据类型(引用类型): Object,Array,Function等:两边的引用地址如果一致的话,是相等的
     arr1 = [1,2,3];
     arr2 = arr1;
     console.log(arr1 === arr2)   // true

相等运算符 ==

非严格匹配: 会类型转换,但是有前提条件一共有五种情况
(接下来的代码以 x == y 为示例)

  1. x和y都是null或undefined:
    规则: 没有隐式类型转换,无条件返回true




console.log ( null == undefined );//true
console.log ( null == null );//true
console.log ( undefined == undefined );//true
  • x或y是NaN : NaN与任何数字都不等
    规则:没有隐式类型转换,无条件返回false

  • 
    
    
    console.log ( NaN == NaN );//false
    
  • x和y都是string,boolean,number
    规则:有隐式类型转换,会将不是number类型的数据转成number

  • 
    
    
    console.log ( 1 == true );//true    (1) 1 == Number(true)
    console.log ( 1 == "true" );//false   (1) 1 == Number('true')
    console.log ( 1 == ! "true" );//false  (1) 1 == !Boolean('true')  (2) 1 == !true  (3) 1 == false  (4)1 == Number(false)
    console.log ( 0 == ! "true" );//true
    console.log(true == 'true') // false
    
  • x或y是复杂数据类型 : 会先获取复杂数据类型的原始值之后再左比较
    复杂数据类型的原始值: 先调用valueOf方法,然后调用toString方法
    valueOf:一般默认返回自身
    数组的toString:默认会调用join方法拼接每个元素并且返回拼接后的字符串

  • 
    
    
    console.log ( [].toString () );//空字符串
    console.log ( {}.toString () );//[object Object]
    注意:  空数组的toString()方法会得到空字符串,
          而空对象的toString()方法会得到字符串[object Object] (注意第一个小写o,第二个大写O哟)
    
    console.log ( [ 1, 2, 3 ].valueOf().toString());//‘1,2,3’
    console.log ( [ 1, 2, 3 ] == "1,2,3" );//true  (1)[1,2,3].toString() == '1,2,3'  (2)'1,2,3' == '1,2,3'
    console.log({} == '[object Object]');//true
    
  • x和y都是复杂数据类型 :
    规则只比较地址,如果地址一致则返回true,否则返回false

  • 
    
    
    var arr1 = [10,20,30];
    var arr2 = [10,20,30];
    var arr3 = arr1;//将arr1的地址拷贝给arr3
           
    console.log ( arr1 == arr2 );//虽然arr1与arr2中的数据是一样,但是它们两个不同的地址
    console.log ( arr3 == arr1 );//true  两者地址是一样
           
    console.log ( [] == [] );//false
    console.log ( {} == {} );//false
    

    经典面试题

    
    
    
    注意:八种情况转boolean得到false: 0 -0 NaN undefined null '' false document.all()
    
    console.log([] == 0); //true 
      // 分析:(1) [].valueOf().toString() == 0  (2) Number('') == 0  (3) false == 0  (4) 0 == 0
    console.log(![] == 0); //true
      // 分析: 逻辑非优先级高于关系运算符 ![] = false (空数组转布尔值得到true)
            
    console.log([] == []); //false
    // [] 与右边逻辑非表达式结果比较
    //(1) [] == !Boolean([])   (2) [] == !true  (3)[] == false  (4) [].toString() == false  (5)'' == false   (6)Number('0') == Number(false)
    console.log([] == ![]); //true
    
    onsole.log({} == {}); //false
    // {} 与右边逻辑非表达式结果比较
    //(1){} == !{} (2){} == !true  (3){} == false  (4){}.toString() == false  (5)'[object Object]' == false  (6)Number('[object Object]') == false
    console.log({} == !{}); //false
    

    变态面试题

    
    
    
     var  a = ???
      if(a == 1 && a == 2 && a == 3 ){
          console.log(1)
      }
    
    //如何完善a,使其正确打印1
    
    
    //答案
    var a = {
      i : 0,    //声明一个属性i
        valueOf:function ( ) {
         return ++a.i;    //每调用一次,让对象a的i属性自增一次并且返回
        }
     }
     if (a == 1 && a == 2 && a == 3){  //每一次运算时都会调用一次a的valueOf()方法
      console.log ( "1" );
     }
    

    来源:https://segmentfault.com/a/1190000018637123

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值