Javascript 进阶 3-7 宽鬆相等、严格相等以及隐含转型

严格相等

严格相等就是指使用三个 = 的运算子,也就是 === 以及 !== 来进行比对,在这两个运算子左右两边的运算元,必须是同类型、又同值的状况下才会回传 true。

console.log(1 === '1'); // falseconsole.log(1 === 1); // true// !== 就是严格不等于console.log(1 !== '1'); // trueconsole.log(1 !== 1); // false

但是这个比对也是有例外的时候,例如两个 NaN (Not a Number)进行严格比对的时候是false

console.log(NaN === NaN); // falseconsole.log(+0 === -0); // false

宽鬆相等

宽鬆相等就是指使用两的 = 的运算子,也就是 == 以及 != 来进行比对,在这两个运算子左右两边的运算元,只要是同值的状况下就会回传 true。

布林值、字串会被转换为Number在进行比较

上一篇也有提到,布林值的true 会被转换成数字1 / false则会被转会为数字0。

而在宽鬆比较中,只要是同值,就会回传true。

所以来看下面範例:

console.log(1 == '1'); // true// 逻辑解析console.log(1 == Number('1')); // true

那么如果换成16进位呢?

console.log(17 == '0x11'); // true// 逻辑解析console.log(17 == Number('0x11')); // true

答案也是一样喔~

那么如果是这样呢?

console.log(1 != '1'); // false

因为对于宽鬆相等来说两个1都是一样的,你说数字1不等于字串1吗? 对宽鬆相等来说两者是一样的,所以当然就给你false。

那在看一个比较难一点的喔

console.log('1' == !0); // true

这个要怎么解读呢?

首先左边的字串1会被解析成数字1,这部分应该没问题。

再来是右边的 !0 ,惊叹号就是反转true为false的概念,所以在宽鬆相等中 0 是 false,而false被!反转的话就是true。而true是布林值在宽鬆相等的时候会被转换为数字1 这时候宽鬆相等的两边都是1。

所以当然就回传true。

Null, Undefined

console.log(Number(null), Number(undefined)); // 0, NaNconsole.log(null == 0); // false

这边 console.log(null == 0); // false 主要原因是因为Null, Undefined在宽鬆相等中不会被转换为数字型别,所以当然null并不等于0。

另外,在宽鬆相等下, null 是等于 undefined 的,但在严格相等的时候不等于。

console.log(null == undefined); // trueconsole.log(null === undefined); // false

物件与非物件,使用包裹物件来转换

甚么意思呢? 我们先来看看实例

console.log(10 == [10]); // true=> console.log(10 == Number([10])); // trueconsole.log('A' == ['A']); // true=> console.log('A' == String(['A'])); // true

所以可以看到,当非物件的值,与物件的值在比对的时候,会透过 包裹物件 转换后再进行比对。

刚刚的物件对象是阵列,那现在真的用物鉴比对的话呢?

console.log(String({a: 'a'})); // [object Object]console.log([object Object] == {a: 'a'}); // true

物件的话,都会被 String() 的物件包裹后,得到 [object Object] 的字串结果。

物件与物件的比对

console.log({} == {}); // falseconsole.log([] == []); // false

这边物件跟阵列都属于物件的资料类型,虽然两者的内容都一样,但当两个物件比较的时候,是比较是否在同一个记忆体路径,并且内容相同。

但有一个例外就是 null ,虽然 null 是归类在物件类别,但不论是严格比较还是宽鬆比较,null 之间都会是 true。

console.log(null == null); // trueconsole.log(null === null); // true

再来要讲的範例比较特别,详细内容会到物件的篇章在跟大家说明,现在先稍微提一下有个印象

var a = [];var b = a;console.log(a == b); // true

透过将盛装物件变数(内容是阵列或是物件)直接赋值给另一个变数的状况会连同该物件变数在记忆体的位置及内容一同指定给变数b,所以这时候 a 跟 b 才会相同。

更特别的是,如果今天 b.push(2); 进去的话 a 也会跟着改变

var a = [];var b = a;console.log(a == b); // trueconsole.log(a === b); // trueb.push(2);console.log('a', a); // [2]console.log('b', b); // [2]

最主要希望在这篇文章先让大家记得,当两个物件类别的资料在进行比对的时候,比对的不只是内容,还有物件资料的记忆体路径。

剩下其他详细内容会到物件的篇章在跟大家说明! 汪汪


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章