iT邦幫忙

2023 iThome 鐵人賽

DAY 15
0
自我挑戰組

複習 JavaScript 核心概念系列 第 15

[Day 15] JavaScript 中的相等比較(嚴格相等、寬鬆相等和隱含轉型)

  • 分享至 

  • xImage
  •  

在程式語言中,比較兩個值的相等性是一個常見的操作。在昨天提到的 JavaScript 運算子的種類中,比較運算子 就是拿來比較兩個值的相等性用的。而實際上 JavaScript 的相等比較主要還分成 嚴格相等(strict equality)寬鬆相等(loose equality),這兩種比較方式的規則並不太一樣。另外在比較過程中可能會出現 隱含轉型 的行為。以上是本篇文章的主題。那我們開始吧。


首先,要先知道用於比較相等性的運算子如下。
=== 嚴格相等運算子
== 寬鬆相等運算子
!== 嚴格不相等運算子(結果與 === 相反)
!= 寬鬆不相等運算子(結果與 == 相反)

嚴格相等(strict equality)

嚴格相等(strict equality),或稱為 強相等,使用 === 運算子來比較兩個值。只有在兩個值的型別和值都相同的情況下,嚴格相等才會回傳 true。另外,如果兩個值皆為數字,只要它們是 NaN 以外的同一值,或者 +0 和 -0,則為相等。

'5' === 5; // 回傳 false,因為型別不同
null === undefined; // 回傳 false,因為型別不同
false === 0; // 回傳 false,因為型別不同
7 === [7]; // 回傳 false,因為型別不同

寬鬆相等(loose equality)

寬鬆相等(loose equality),或稱為 弱相等,使用 == 運算子來比較兩個值。當使用寬鬆相等時, JavaScript 會在比較時會進行隱含的型別轉換,然後比較兩個值是否相等。這種比較通常會導致一些意想不到的結果,特別是在不同型別的值進行比較時。

其中 隱含轉型 是指 JavaScript 在某些操作中自動將一種類型的值轉換為另一種類型的值。
來看看以下例子:

'5' == 5; // 回傳 true,因為字串 '5' 會被隱含轉換成數字 5 再作比較
null == undefined; // 回傳 true,因為規範中寬鬆比較的 null 和 undefined 是相等的
false == 0; // 回傳 true,因為布林值 false 會被隱含轉換成數字 0 再作比較
7 == [7]; // 回傳 false,因為陣列 [7] 會先被隱含轉換成字串 '7',並接著嘗試轉換成數字 7 再作比較

其他容易搞錯的例子

[1, 2] == '1,2'; // true,因為陣列 [1, 2] 會被隱含轉換成字串 '1,2',再作比較

'' === false; // false,因為型別不同
'' == false; // true,因為空字串 '' 會被轉換成 false 再作比較

[] == ''; // true,因為空陣列 [] 會被隱含轉換成字串 '',再作比較

[1, 2] == true; // true,因為陣列 [1, 2] 會被轉換成字串 '1,2',又非空字串會被轉換成 true 再作比較
[] == false; // true,因為空陣列 [] 會被隱含轉換成字串 '',又空字串會被轉換成 false 再作比較

NaN == NaN;  // false
+0 === -0; // true
let score;

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

console.log(score == undefined); // true
console.log(score == null); // true
const obj1 = { key: 'value' };
const obj2 = { key: 'value' };
const obj3 = obj2;

console.log(obj1 == obj2); // false,因為 obj1 和 obj2 是不同的物件參考
console.log(obj2 === obj3); // true,因為 obj2 和 obj3 是相同的物件參考

總結

今天介紹了 嚴格相等(strict equality)寬鬆相等(loose equality) 的差別,以及舉了一些例子來聊解 隱含轉型 是如何影響比較結果的。我是較少在使用寬鬆相等(==、!=)的比較方式,畢竟太「寬鬆」可能帶來一些淺在的問題,例如以下例子:

let totalNum = 0;
conet a = '5';

if(a == 5) {
  totalNum = totalNum + a;
  console.log(total); // 輸出字串的 '05'
}

此外更多規則可參考 MDN文件
那麼今天就到這邊,我們明天見~
/images/emoticon/emoticon37.gif


上一篇
[Day 14] 運算子的優先性及相依性
下一篇
[Day 16] Truthy 和 Falsy
系列文
複習 JavaScript 核心概念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言