zoukankan      html  css  js  c++  java
  • JS/JavaScript中两个等号 == 和 三个等号 === 的区别

    一、概念 == 和 === 
    (1)  "=="叫做相等运算符,"==="叫做严格运算符。
    (2) ==,equality -> 等同  的意思, 两边值类型不同的时候,要先进行类型转换为同一类型后,再比较值是否相等。 
    ===,identity -> 恒等 的意思,不做类型转换,类型不同的结果一定不等。 
    (3) "=="表示只要值相等即可为真,而"==="则要求不仅值相等,而且也要求类型相同。

    对于明确数据类型的用===更为可靠,JavaScript是一门弱类型语言,表达式运算赋值等操作都会导致类型转换。而一些隐式转换会带来一些意想不到的后果。
    编程建议:尽量使用严格运算符 ===。因为"=="不严谨,可能会带来一些违反直觉的后果。

    二、严格运算符 === 的运算规则
    严格运算符===的运算规则如下,
    (1)不同类型值
    如果两个值的类型不同,直接返回false。
    (2)同一类的原始类型值
    同一类型的原始类型的值(数值number、字符串string、布尔值boolean)比较时,值相同就返回true,值不同就返回false。
    (3)同一类的复合类型值/高级类型
    两个复合类型(对象Object、数组Array、函数Funtion)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个对象。即“地址指针”是否相等。
    (4)undefined和null
    //undefined 和 null 与自身严格相等。
    
    
    null === null  //true
    undefined === undefined  //true
    undefined === null  //true

    三、相等运算符 "== "的运算规则
    相等运算符"=="在比较相同类型的数据时,与严格运算符"==="完全一样。
    在比较不同类型的数据时,相等运算符"=="会先将数据进行类型转换,然后再用严格相等运算符"==="比较。类型转换规则如下:
    (1)原始类型的值
    原始类型的数据会转换成数值类型再进行比较。字符串和布尔值都会转换成数值
    (2)对象与原始类型值比较
    对象(这里指广义的对象,包括数值和函数)与原始类型的值比较时,对象转化成原始类型的值,再进行比较。
    (3)undefined和null
    undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true。
    (4)相等运算符"=="的缺点
    相等运算符"=="隐藏的类型转换,会带来一些违反直觉的结果。
    1. '' == '0' // false
    2. 0 == '' // true
    3. 0 == '0' // true
    4. false == 'false' // false
    5. false == '0' // true
    6. false == undefined // false
    7. false == null // false
    8. null == undefined // true
    9. ' ' == 0 // true
    这就是为什么建议尽量不要使用相等运算符"=="
    至于使用相等运算符"=="会不会对后续代码造成意外影响,答案是有可能会。
    建议尽量使用"===",因为"=="不严谨,可能会带来一些违反直觉的后果。比如我们常使用的对象,有时获取不到而被赋值为undefine的情况。
    1. var a = undefined;
    2. if(!a){
    3. console.log("1"); //1
    4. }
    5.  
    6. var a = undefined;
    7. if(a == null){
    8. console.log("1"); //1
    9. }
    10.  
    11. var a = undefined;
    12. if(a === null){
    13. console.log("1"); //无输出
    14. }
    也就是说当a为undefined时,输出的值会有变化,而在编程中对象变成undefined实在是太常见了。
    “==”带来的便利性抵不上其带来的复杂性和bug成本。举个简单的例子,团队协作中你肯定需要读别人的代码。而当你看到“==”时,要判断清楚作者的代码意图是确实需要转类型,还是无所谓要不要转类型只是随手写了,还是不应该转型但是写错了……所花费的脑力和时间比明确的“===”(加上可能需要的明确转型)要多得多。

    三、JavaScript中 "==" 的坑
    JavaScript 里各种比较坑你踩过吗?比如下面这些表达式,你猜猜答案是什么:
    undefined == null
    
    
    false == "      "
    "" == 0
    123 == "123"
    "1" == true

    上面的答案都是true 虽然你可以说,既然语言这样设计,肯定有它自己的道理啊。但是别忘了,JavaScript 是一个动态类型语言啊,假如你写了这样的代码:
    function fix(n) {
    
    
        if (n == 0) return n + 1;
        return n + 2;
    }

    如果输入n为字符串值"0"的话,恭喜你,你的程序爆炸啦!  你将会得到字符串"01"作为返回值,而不是你想要的数字1。所以一句话概括没有类型限制,类型转换的后果将是不可预料的。
    而且你写的程序很大的话,你可能在这上面浪费好几个小时找 bug。所以在自己需求明确的情况下,为什么不写===来避免可能的 bug 呢?

    那么这种不严格比较确实就一无是处吗?不,比如你想判断一个字符串看起来是不是空白的(由空白字符组成),可以这样写:
    if (typeof str === "string" && str == false)
    console.log("The string is full of white spaces!");
    

    四、JavaScript中 == 和 === 的详细比较规则
    下面分别说明: 
    先说 ===,这个比较简单。下面的规则用来判断两个值是否===相等: 
    1、如果类型不同,就[不相等] 
    2、如果两个都是数值,并且是同一个值,那么[相等];(!例外)的是,如果其中至少一个是NaN,那么[不相等]。(判断一个值是否是NaN,只能用isNaN()来判断) 
    3、如果两个都是字符串,每个位置的字符都一样,那么[相等];否则[不相等]。 
    4、如果两个值都是true,或者都是false,那么[相等]。 
    5、如果两个值都引用同一个对象或函数,那么[相等];否则[不相等]。 
    6、如果两个值都是null,或者都是undefined,那么[相等]。 

    再说 ==,根据以下规则: 
    1、如果两个值类型相同,进行 === 比较。 
    2、如果两个值类型不同,他们可能相等。根据下面规则进行类型转换再比较: 
    a、如果一个是null、一个是undefined,那么[相等]。 
    b、如果一个是字符串,一个是数值,把字符串转换成数值再进行比较。 
    c、如果任一值是 true,把它转换成 1 再比较;如果任一值是 false,把它转换成 0 再比较。 
    d、如果一个是对象,另一个是数值或字符串,把对象转换成基础类型的值再比较。对象转换成基础类型,利用它的toString或者valueOf方法。 js核心内置类,会尝试valueOf先于toString;例外的是Date,Date利用的是toString转换。
    e、任何其他组合,都[不相等]。 

    举例: 
    "1" == true 
    类型不等,true会先转换成数值 1,现在变成 "1" == 1,再把"1"转换成 1,比较 1 == 1, 相等。 

    = 赋值运算符 
    == 等于 
    === 严格等于 
    var a = 3; 
    
    var b = "3"; 
    
    
    
    console.info(a==b); //返回 true 
    console.info(a===b); //返回 false 

    因为a,b的类型不一样 
    ===用来进行严格的比较判断。

    五、总结
    共2点结论: 
    1、编程建议:尽量使用严格运算符 ===。因为"=="不严谨,可能会带来一些违反直觉和意想不到的后果。
    2、少用==:因为没有类型限制,类型转换的后果将是不可预料的。
     
    原文链接:https://blog.csdn.net/chenchunlin526/article/details/78850171
  • 相关阅读:
    Mysql安装
    mysql 密码过期
    svn 合并分支
    idea 分支主干管理
    linux删除数据恢复,extundelete
    linux 转换文件编码
    sina 接口 根据ip获取各个国家和地区
    SQL中char、varchar、nvarchar的区别
    C#中virtual和abstract区别,举例子
    父类和子类的关系、代码例子
  • 原文地址:https://www.cnblogs.com/uzxin/p/13651408.html
Copyright © 2011-2022 走看看