點燈坊

失くすものさえない今が強くなるチャンスよ

ECMAScript 之 Equality Operator

Sam Xiao's Avatar 2020-01-27

ECMAScript 有別於其他語言,同時提供了 ===== 兩套 Equality Operator,很多人只使用 ===,事實上只要了解 == 的規則,就能善用 ==

Version

macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.274
ECMAScript 2015

==

當使用 == 比較時,若 == 兩側的型別不同, ECMAScript 會嘗試依照以下規則 自動轉型

  • 若其中一值為 boolean,會先將 true 轉成 1false 轉成 0 後再比較
  • 若 string 與 number 比較,則 string 會透過 Number() 轉成 number 後再比較
  • 若 object 與 primitive 比較,則會先使用 valueOf() 取得 object 的 primitive 值之後再比較
  • nullundefined 視為 == 相等

簡言之 == 只能比較 number,各型別都會 自動轉型 成 number 後再進行比較

Boolean vs. Number

1 == true // ?
0 == true // ?

1 == false // ?
0 == false // ?

true 先自動轉型成 1false 先自動轉型成 0 之後再進行比較。

equal000

String vs. Number

1 == '1' // ?
0 == '1' // ?

String 會先透過 Number() 轉成 number 後,兩個 number 再進行比較。

equal001

String vs. Boolean

'1' == true // ?
'0' == true // ?

'1' == false // ?
'0' == false // ?

由於 == 只能比較 number,因此 string 與 boolean 無法直接比較,string 與 boolean 會先轉成 number 後再進行比較。

equal002

Primitive vs. Primitive Wrapper

1 == new Number(1) // ?
'hello' == new String('hello') // ?
true == new Boolean(true) // ?

new Number() 為 object,會先透過 valueOf() 取得 primitive 再進行比較。

equal006

===

當使用 === 比較時,則不會做 自動轉型,必須 type 與 value 都相等時才會回傳 true,否則回傳 false

Boolean vs. Number

1 === true // ?
0 === true // ?

1 === false // ?
0 === false // ?

由於 === 不會自動轉型,兩者 type 已經不同,一律回傳 false

equal003

String vs. Number

1 === '1' // ?
0 === '1' // ?

由於 === 不會自動轉型,兩者 type 已經不同,一律回傳 false

equal004

String vs. Boolean

'1' === true // ?
'0' === true // ?

'1' === false // ?
'0' === false // ?

由於 === 不會自動轉型,兩者 type 已經不同,一律回傳 false

equal005

Primitive vs. Primitive Wrapper

1 === new Number(1) // ?
'hello' === new String('hello') // ?
true === new Boolean(true) // ?

由於 === 不會自動轉型,primitive 與 object 的 type 已經不同,一律回傳 false

equal007

Application

ECMAScript 大都使用 ===,但實務上有兩個地方會使用 ==

Number || string

let data0 = 123
let data1 = '123'

let fn = num => num == 123

fn(data0) // ?
fn(data1) // ?

若確定 number 123 與 string 123 都是能接受 argument,可直接使用 == 判斷即可,ECMAScript 會自動將 string 轉型成 number。

equal008

null || undefined

let data0 = null
let data1 = undefined

let fn = num => (num == null)

fn(data0) // ?
fn(data1) // ?

若想同時判斷 nullundefined,可直接 == null== undefined 即可,因為 ECMAScript 在 spec 強制定義 null == undefined 為 true。

equal009

Conclusion

  • == 其實很好用,唯必須熟悉 ECMAScript 的 自動轉型 規則,則不必手動轉型讓 code 變髒

Reference

許國政, 008 天重新認識 JavaScript
Dr. Axel Rauschmayer, Speaking JavaScript