(Day08) 隱含轉型 - 轉成 Boolean & 寬鬆相等 vs 嚴格相等

前言

上一篇介紹了數字型別、字串型別的隱含轉型,接下來介紹剩餘的隱含轉行,剩餘隱含轉型大約分成以下三種:

  • 隱含轉型 : 轉成 Boolean
  • 運算子 || 與 &&
  • 寬鬆相等(Loose Equals) vs 嚴格相等(Strict Equals)

隱含轉型 : 轉成 Boolean

關於轉成布林值這一塊,其實大多都是用在判斷式的條件判斷中,當條件判斷成立,條件判斷會透過隱含轉型轉成 true 因此條件下的程式碼才能被執行, 例如:

  • if() 中的條件判斷。
  • for( xx; xx; xx; ) 中,第二句的條件判斷。
  • while() 中的條件判斷。
  • xx ? OO1 : OO2 三元運算中的第一個條件判斷。
  • 邏輯運算子中 ||&& 最左邊的操作,會被轉換。

接下來同樣用程式碼來看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var a = 666
var b = 'test'
var c
var d = null
if (a) {
// true
console.log('執行成功'); // 執行成功
}
while (c) {
// false
console.log('不執行');
}

d ? a : b // 'test'
// d 被轉成 false ,因此執行 b

if ((a && d) || c) {
//fasle
console.log('不執行');
}

上面比較特別的就是 邏輯運算子 ||&& 這部分接下來會再說明。

邏輯運算子 || 與 &&

實做中我們很常用到判斷式搭配 ||&& ,例如

1
2
3
4
5
var width = 768 
var fontSize = 16
if( width >= 1200 || fontSize === 16 ){
xxx
}

這會讓我們有種錯覺 ||&& 運算子就是用來判斷 truefalse 的方法,然而我們在上面 『隱含轉型 : 轉成 Boolean 』這部分就有提到, if() 中的判斷式會被 JavaScript 根據是否達成,轉成 truefalse , 也因此 ||&& 運算子不是單純判斷 truefalse 的方法,而這兩個運算子語法的功能實際上是 : 在前後運算元中選擇一個使用,這邊也使用程式碼當作範例:

1
2
3
4
5
6
7
8
9
var a = 123;
var b = "test";
var c = null;

a || b; // 123
a && b; // "test"

c || b; // "test"
c && b; // null

根據 MDN 文件描述:

&& 的狀況是當第一個操作 是 false 時,&& 會回傳第一個運算子,反之第一個是 true 回傳第二個運算子,因此在判斷式中使用 && 是必須兩個條件都是 true 判斷式才會被執行。

|| 運算子正好相反,當第一個操作 是 false|| 會回傳第二個運算子,反之第一個是 true 時,|| 便會回傳第一個操作結果,因此在判斷式中使用 || 指要一個條件達成 true ,判斷式就會被執行。

寬鬆相等(Loose Equals) vs 嚴格相等(Strict Equals)

在 JavaScript 中使用 === 比較運算子,我們稱做 嚴格相等(Strict Equals),使用這種方法做對比並不會執行隱含轉型的動作。

而使用 == 比較運算子做對比,稱做 寬鬆相等(Loose Equals),使用這種方法做對比則會執行 隱含轉型 的動作,比如這個範例:

1
2
'123' == 123 //true  字串 123 會被隱含轉型 
'123' === 123 //false 兩者型別不同

那麼關於 == 運算子在轉型上是否有什麼規則?

這邊可以透過 MDN 的文件來了解其規則

寬鬆相等

接者同樣使用程式碼當作範例:

1
1 == 'true' //false

從上面圖表會發現,字串對上數字是 ToNumber(A) === B ,也就是兩者都會轉換成數字型別做對比。

1
[1,2,3] == '1,2,3' //true

陣列屬於物件的一種,按照圖表會是 ToPrimitive(A) == B ,按照 MDN 文件說明

ToPrimitive(A) 嘗試從物件轉換成原生值,透過嘗試對 A 使用 A.toString 和 A.valueOf 方法。

也就是 [1,2,3] 會被 toString() 轉成字串 。

1
false == '0' // true

布林對字串會是 ToNumber(A) === ToNumber(B) 兩者都會被成數字,結果都是 0 。

1
true == 'true' //false

同上布林對字串會是 ToNumber(A) === ToNumber(B) ,字串 'true' 也會被 ToNumber() 轉換,轉換後是 NaN

最後關於寬鬆相等,網路上也有人整理滿完整的圖表,這邊也分享一下:
https://thomas-yang.me/projects/oh-my-dear-js/

參考資料