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. ' \t\r\n ' == 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 == " \t    "
"" == 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
posted @ 2020-09-11 14:05  uzxin  阅读(599)  评论(0编辑  收藏  举报