JS/JavaScript中两个等号 == 和 三个等号 === 的区别

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、少用==:因为没有类型限制,类型转换的后果将是不可预料的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值