宽松相等(==)和严格相等(===)

宽松相等和严格相等

最开始我没有阅读《你不知道的JavaScript》的时候,我对 == 和 === 的理解就恰如书中说的常见的误区一样:“ == 是检查值是否相等, ===是判断值和类型是否相等”。这样的理解我一直没有怀疑,毕竟平时写代码的时候,我就是这样用的,也没有遇到什么问题。但是编程,准确知道你写的每一句代码是干什么的,怎么干的,非常重要,这样才相当于代码是你实现自己思维的载具,而不是坐上了不知道可能会去哪里的火车。

  • 这里写下我现在对 == 和 === 的理解:“ == 会在比较中进行强制类型转换,而 === 不会”
1. == 和 === 有何不同?
  • 首先它们会判断两边值的类型是否相同,如果两边的值类型相同,显然 == 和 === 进行的是同样的算法;如果不同,== 就会执行类型转换,然后再判断是否相等。而 ===此时已经可以直接返回 false 了。
2. == 如何进行类型转换?

当我深以为理解 == 的时候,我又遇到了这样一个坑:

var a = '24';
var b = true;
console.log(a == b) // true or false?               false!!!!!!!

按照最开始的理解:== 判断值是否相等。24 的值为 true ,所以结果是 true。可我打印结果之后结果是 false !为什么?下面解释。

2.1 布尔值和其他数据类型比较

如何从刚才那个坑跳出来?我后来学到了这个规范:

  1. 如果判断 a == b,a是布尔值,那么判断的是 Number(a) == b;
  2. 如果判断 a == b,b是布尔值,那么判断的是 a == Number(b);
(a == b) --> ('24' == true) --> ('24' == 1) --> (24 == 1) //false
  • 所以得到的结果为false。因为如此,后来我再也没有偷懒少打一个 = 来判断 == true了。
2.2 数字和字符串比较

在2.1 中已经看到了,数字和字符串判断的规范是这样的

  1. 如果判断 a==b, a是字符串,那么判断的是 Number(a) == b;
  2. 如果判断 a==b, b是字符串,那么判断的是 a == Number(b);
2.3 null 和 undefined 比较
undefined == null; //true
null == undefined; //true
  • 它们之间可以互相交换,在 == 中是等价的。
2.4 对象和非对象之间的相等比较

先说转换规则:

  1. 如果是判断 Object == a ,则判断的是 ToPrimitive(Object) == a。
  2. 如果是判断 a == Object ,则判断的是 a == ToPrimitive(Object)。
  • ToPrimitive执行的是 Object.valueOf(),然后再对它执行的toString()。
var a = 24;
var b = [24];
console.log(a == b); // true
(a == b) --> (24 == b.valueOf().toString()) --> (24 == '24') --> (24 == 24) -->true
3. 容易被误导的情况

前面的规则我已经掌握了,这里写出一些容易误导人的情况,以便自己以后遇到好区分:

var a = [undefined,null,'',NaN,+0,false]
for(var i = 0; i < a.length; i++){
	console.log('0' == a[i]);
	// (4) false (2) true
}
  • 上式中 ‘0’ == false 为 true ,按照平常的理解,字符串中只有 ‘ ’ 经过转换才是 false,所以结果应该为 false 才对。但是用刚才讲的规范,其实是先用布尔值比较规则,然后再用数字和字符串比较规则,最后比较的其实是 0 == 0,结果当然为 true 了。

接下来再列出来其他容易被误导的情况,看看自己能不能运用规范进行判断:

  • false 特殊的比较情况
false == null;         // false 
false == undefined;    // false 
false == NaN;          // false 
false == {};           // false
false == 0;            // true
false == "";           // true  (0 == '') --> (0 == 0)
false == [];           // true  (false == [ ].valueOf( ).toString( )) --> (false == "")

  • “ ” 特殊的比较情况
"" == null;            // false 
"" == undefined;       // false 
"" == NaN;             // false 
"" == {};              // false 
"" == 0;               // true 
"" == [];              // true ("" == [ ].valueOf( ).toString( )) --> ("" == "")

  • 0 特殊比较情况
0 == null;             // false 
0 == undefined;        // false 
0 == NaN;              // false 
0 == {};               // false (0 == { } Object.valueOf( ).toString( )) --> (0 == "[Object,Object]")
0 == [];               // true (0 == [ ].valueOf( ).toString( )) --> (0 == "") --> (0 == 0)

按照规范来看看下面这个:

[] == ![] // true ?????  ([] == false)
  • 这里的 ! [ ] 进行的是布尔值的强制转换,我在另外一篇文章有描述,[ ] 是一个 “真” 值,所以 ![ ] 为 false。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值