iT邦幫忙

0

Javascript 進階 3-7 寬鬆相等、嚴格相等以及隱含轉型

嚴格相等

嚴格相等就是指使用三個 = 的運算子,也就是 === 以及 !== 來進行比對,在這兩個運算子左右兩邊的運算元,必須是同類型、又同值的狀況下才會回傳 true。

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

// !== 就是嚴格不等於

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

但是這個比對也是有例外的時候,例如兩個 NaN (Not a Number)進行嚴格比對的時候是false

console.log(NaN === NaN); // false
console.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, NaN
console.log(null == 0); // false

這邊 console.log(null == 0); // false 主要原因是因為Null, Undefined在寬鬆相等中不會被轉換為數字型別,所以當然null並不等於0。

另外,在寬鬆相等下, null 是等於 undefined 的,但在嚴格相等的時候不等於。

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

物件與非物件,使用包裹物件來轉換

甚麼意思呢? 我們先來看看實例

console.log(10 == [10]); // true
=> console.log(10 == Number([10])); // true

console.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({} == {}); // false
console.log([] == []); // false

這邊物件跟陣列都屬於物件的資料類型,雖然兩者的內容都一樣,但當兩個物件比較的時候,是比較是否在同一個記憶體路徑,並且內容相同

但有一個例外就是 null ,雖然 null 是歸類在物件類別,但不論是嚴格比較還是寬鬆比較,null 之間都會是 true。

console.log(null == null); // true
console.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); // true
console.log(a === b); // true

b.push(2);

console.log('a', a); // [2]
console.log('b', b); // [2]

最主要希望在這篇文章先讓大家記得,當兩個物件類別的資料在進行比對的時候,比對的不只是內容,還有物件資料的記憶體路徑。

剩下其他詳細內容會到物件的篇章在跟大家說明! 汪汪


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言