[JS奇怪的世界]No.18 比較運算子

比較運算子

將下來講講比較運算子,首先讓我們試著用程式碼來理解 ↓

1
console.log(1 < 2 < 3);

答案是什麼?true 合理嗎?很合理,因為 1 小於 2 小於 3,正解無誤。

但是如果改成這樣子呢?

1
console.log(3 < 2 < 1);

答案應該會是 false 吧,讓我們來看看。

答案

WT…怎麼會是 true,讓我們試著用唸出來的 3 小於 2 小於 1,感覺似對非對,這邊的原因是出在運算子的優先性及相依性(我覺得應該叫順序性比較清楚)導致,在這一條運算子中,大家的優先性是一樣的(都是小於),所以這時候就要改相依性來判斷。

運算子中 「 < 」 是左相依性,所以從左邊的會先被執行 3 小於 2 會出現什麼?

1
console.log(3 < 2);

false

那接下來當 false 去做比對呢?

1
console.log(false < 1);

這個時候因為 JavaScript 的動態型別特性,它會將這一行運算子強制轉型,此時的 false 被轉成了數值 (Number),而 false 轉成數字代表著什麼?就是 0

1
console.log(0 < 1);

這也就是為什麼會輸出 true 的原因。

  • 0 代表 false
  • 1 代表 true

以人的角度來講 console.log(3 < 2 < 1);,絕對是錯的,但在 JavaScript 中是合理正確的。

所以我們回到一開始的範例來分析。

1
console.log(1 < 2 < 3);

剛剛有講到小於運算子是左相依性,所以會優先判定 1 < 21 小於 2,答案是 true,此時程式又變成了這樣。

1
console.log(true < 3);

在經過 JavaScript 的強制轉型後程式碼就又會變成這樣子。

1
console.log(1 < 3);

1 小於 3 ,沒錯,所以是 true

有時候我們可以透過強轉型別語法來將字串的數字變成數值就像這樣

1
Number('1');

但是如果我們強轉的字串不是數值呢?

1
Number('哈囉');

不是數值

我們會得到一個特別的東西,「NaN」,NaN 表示[不是數字] (Not a Number)。

課程中也有轉換 Undefined 及 Null。

1
Number(undefined);

只會得到 NaN (我們也可以由這邊知道 undefined 其實是一個值,特殊的關鍵字)。

那 Null 呢?

1
Number(Null);

JavaScript 則將 Null 定義為 0。

我們可以知道強轉型別是很危險的事情,所以沒事不要去做強轉。

==

== 是一個雙等號運算子,我們可以這樣寫 ↓

1
1 == 1;

我們會得到一個答案 true,這個運算子會回傳 true 或是 false

但如果這樣子呢?

1
1 == '1';

你一樣會得到一個 true,為什麼?這是因為 JavaScript 會將這兩個參數強制轉型成一樣的型別做比較,但是這會引發一些很奇怪的事情例如…

1
2
3
0 == false;
var a = false;
a == 0;

雙等號

那 === 呢?

=== 與 == 差異在於,JavaScript 不會做強制轉型的動作(也可以理解成我們禁止 JavaScript 幫我們做強制轉型),直接用目前型別去做比較

1
2
3
0 === false;
var a = false;
a === 0;

三等號

那這也是為什麼我們在撰寫 JavaScript 的時候都會建議不要使用 ‵== ,而是使用 ===,這個動作可以減少很多奇怪的問題。

=== 是甚麼意思?簡單來講就是嚴謹、嚴格模式,我不要你 (JavaScript) 轉換型別,直接用當前型別做比較就好的意思。

更詳細可以看這個 MDN 文件

圖源

JavaScript 全攻略:克服 JS 奇怪的部分