zoukankan      html  css  js  c++  java
  • 深入探究JavaScript中的比较问题

    先用最近遇到的几个问题做引子:

        1 console.log(null==undefined); //true   
        2 console.log(null==false);//false
        3 console.log(null==0);//false
        4 console.log(0==undefined);//false
        5 console.log(false==undefined); //false
        6 console.log([]==![]);//true
    

    各位读者如果不确定的话,可以在各自的浏览器中实验一下。
    怎么样?答案和自己想的一致吗?如果不一致,那就跟随笔者探索一下其中的奥秘吧!

    首先我们来分析一下undefinednull的区别。

    首先来看下面这个例子:

        Number(null)
        //0
        10+null
        //10
    

    这样看来,null被设计成可以自动转为0.

    JavaScript的最初版本是这样区分的,null是一个表示“无”的对象,转为数值时为0;undefined是一个表示“无”的原始值,转为数值时为NaN。

    null表示“没有对象”,即该处不应该有值。典型用法是:

    • 作为函数的参数,表示该函数的参数不是对象。

    • 作为对象原型链的终点。

       Object.getPrototypeOf(Object.prototype)
       // null
      

    undefined表示“缺少值”,就是此处应该有一个值,但是还没有定义。典型用法是:

    • 变量被声明了,但没有赋值时,就等于undefined。

    • 调用函数时,应该提供的参数没有提供,该参数等于undefined。

    • 对象没有赋值的属性,该属性的值为undefined

    • 函数没有返回值时,默认返回undefined

        var i;
        i //undefined
        
        function f(x){console.log(x)}
        f() //undefined
        
        var o=new Object();
        o.p //undefined
        
        var x=f();
        x //undefined
      

    那么为什么null==undefined呢?

    ECMAScript认为,undefined是从null派生出来的,所以把它们定义为相等的。但是,如果在一些情况下,我们一定要区分这两个值,那应该怎么办呢?可以使用下面的两种方法。

        alert(null===undefined);
        alert(typeof null == typeof undefined)
    

    此时,我们已经解决了第5个问题,那么其他的如何解释呢?
    下面是摘自stackflow上大神的解释。

    The Abstract Equality Comparison Algorithm

    The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as follows:

    1. If Type(x) is the same as Type(y), then

      1.1 If Type(x) is Undefined, return true.

      1.2 If Type(x) is Null, return true.

      1.3 If Type(x) is Number, then

      • If x is NaN, return false.

      • If y is NaN, return false.

      • If x is the same Number value as y, return true.

      • If x is +0 and y is −0, return true.

      • If x is −0 and y is +0, return true.

      • Return false.

      1.4 If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
      1.5 If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false.
      1.6 Return true if x and y refer to the same object. Otherwise, return false.

    2. If x is null and y is undefined, return true.

    3. If x is undefined and y is null, return true.

    4. If Type(x) is Number and Type(y) is String,return the result of the comparison x == ToNumber(y).

    5. If Type(x) is String and Type(y) is Number,return the result of the comparison ToNumber(x) == y.

    6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.

    7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).

    8. If Type(x) is either String or Number and Type(y) is Object,return the result of the comparison x == ToPrimitive(y).

    9. If Type(x) is Object and Type(y) is either String or Number,return the result of the comparison ToPrimitive(x) == y.

    基于以上规则,我们再来看看最初的题目:
    以第6题为例:

    []是数组,而![]是boolean值。当你使用==比较两个不同类型的对象时需要转化为可比较的类型,根据上述规则第7条,使用ToNumber转化后,![]返回0,[]返回0,所以为true。

  • 相关阅读:
    【LeetCode-树】找树左下角的值
    【LeetCode-贪心】合并区间
    MongoDB3.6版本新增特性
    MongoDB initial sync过程
    MongoDB3.4版本新增特性
    保险配置原则
    MongoDB批量操作时字段为null时没有入库
    Kafka消费者没有收到通知的分析
    Git分支的管理
    NoSQLBooster如何MongoDB的部分文档从一个集合拷贝到另外一个集合中
  • 原文地址:https://www.cnblogs.com/depsi/p/5025606.html
Copyright © 2011-2022 走看看