Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

本文為「JS 101:資料型別」系列第 10 篇

JavaScript 自動轉換型態( Type Coercion)與比較運算子完整解析

最後更新:2026年3月4日JavaScript

看看這幾行程式碼的輸出結果:

console.log(8 * null)    // 0
console.log("5" - 1)     // 4
console.log("5" + 1)     // "51"
console.log("five" * 2)  // NaN
console.log(false == 0)  // true

為什麼 "5" - 1 等於 4,但 "5" + 1 卻等於 "51"?

為什麼 8 * null 不報錯,反而輸出 0?

要搞懂這些奇怪的結果,我們要先從「型別轉換」說起。

什麼是型別轉換?

每一個值在 JavaScript 裡都有它的型別(type),用來告訴程式「這個值是什麼種類的資料」。

JavaScript 常見的型別有以下幾種:

型別說明範例
number數字42、3.14、NaN
string字串"hello"、"5"
boolean布林值true、false
null刻意設為空值null
undefined尚未被賦值undefined
說明數字
範例42、3.14、NaN
說明字串
範例"hello"、"5"
說明布林值
範例true、false
說明刻意設為空值
範例null
說明尚未被賦值
範例undefined

但在實際寫程式的時候,你常常會遇到「型別不匹配」的情況。

例如網頁上有一個輸入框,使用者在裡面打了 5。

你可能以為程式拿到的是數字 5,但其實輸入框回傳的值一律是字串,所以程式拿到的是 "5"。

這時候如果你想拿它來做數學運算,就需要先把字串 "5" 轉換成數字 5。

這就是型別轉換:把一個值從某個型別,轉換成另一個型別。

最直接的方式是主動寫明要轉換成什麼型別,你決定什麼時候轉、轉成什麼,所以結果完全在你的掌控之中。

JavaScript 提供了幾個內建的寫法,可以直接指定要轉換的型別,你現在不需要深究這些寫法的原理,只要知道它們的用途就好:

Number("5")   // 把字串 "5" 轉成數字 5
String(123)   // 把數字 123 轉成字串 "123"
Boolean(0)    // 把數字 0 轉成布林值 false

什麼是自動型別轉換?

上面的主動轉換很直觀,因為你明確寫出了要轉換成什麼型別。

但如果每次運算都要手動轉型,對新手來說會很繁瑣。

JavaScript 當初的設計目標,是讓沒有程式背景的人也能快速上手。

為了達到這個目標,它選擇成為一個「寬容」的語言——當程式遇到型別不符合的情況,不要直接報錯讓整個網頁壞掉,而是盡量猜測你的意圖,自動轉換後繼續執行。

這個行為就叫做自動型別轉換(type coercion)。

以開頭的 "5" - 1 為例,你沒有寫任何轉換,但 JavaScript 猜測你想做數字相減,所以自動把字串 "5" 轉成數字 5,然後繼續執行,得出 4。

這個設計的出發點是好的,但問題在於,JavaScript 猜測的結果不一定是你預期的。

讓我們逐一拆解開頭的例子,搞清楚每一行發生了什麼事。

8 * null → 0

null 被轉換成數字 0,所以 8 * 0 = 0。

"5" - 1 → 4

字串 "5" 被轉換成數字 5,所以 5 - 1 = 4。

"5" + 1 → "51"

這裡很容易混淆:+ 運算子有兩個用途——數字相加和字串串接。

當其中一側是字串,+ 會優先選擇串接字串,所以數字 1 被轉換成字串 "1",結果變成 "51"。

"five" * 2 → NaN

"five" 沒辦法被轉換成有意義的數字,所以 JavaScript 會給它一個特殊值:NaN(Not a Number)。

有一點要特別注意:對 NaN 做任何算數運算,結果都還是 NaN。

console.log(NaN + 1)   // NaN
console.log(NaN * 100) // NaN

如果你的程式輸出一直是 NaN,很可能就是在某個地方發生了非預期的型別轉換。

== 比較運算子的轉換邏輯

前面介紹的自動型別轉換,都發生在算術運算(+、-、*)。

但其實比較兩個值的時候,也會發生自動轉換。

== 是 JavaScript 的比較運算子,用來判斷兩邊的東西是否相等,結果會是 true 或 false。

console.log(5 == 5)             // true
console.log("hello" == "hello") // true
console.log(5 == 3)             // false

當你用 == 比較相同型別的兩個值,邏輯很直覺:兩個值一樣就是 true,不一樣就是 false(NaN 除外,它連自己都不等於自己)。

麻煩的是當型別不同時,== 會先嘗試把其中一個值轉換成另一個的型別,再做比較。

console.log(false == 0)   // true
// false 被轉成 0,實際比較的是:
console.log(0 == 0)       // true

console.log("" == false)  // true
// "" 被轉成 0,false 也被轉成 0,實際比較的是:
console.log(0 == 0)       // true

這就是 == 容易讓人混淆的地方——你可能不會預期空字串和 false 是「相等」的。

null 和 undefined 是特例

前面提到 == 會自動轉換型別再比較,但 null 和 undefined 是例外。

null 和 undefined 用 == 比較時,不管是 null == undefined、null == null、還是 undefined == undefined,結果都是 true:

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

跟其他任何東西比,不管是 0、""、false,結果都是 false,== 不會嘗試轉換它們:

console.log(null == 0)         // false
console.log(null == "")        // false
console.log(undefined == false) // false

為什麼要這樣設計?因為 null 和 undefined 都代表「沒有值」,只是原因不同——null 是你主動設為空值,undefined 是根本還沒賦值。

在實際開發中,你通常不在乎「為什麼沒有值」,只在乎「有沒有值」,所以讓它們用 == 比較時相等,可以一次處理兩種情況。

那要怎麼利用這個特性?來看一個常見的情境。

假設你想確認變數 name 有值(不是 null 也不是 undefined),最直覺的寫法是分開檢查:

if (name !== null && name !== undefined) {
  console.log("Hello, " + name)
}

但因為 null == undefined 是 true,它的相反 null != undefined 就是 false。

這代表 != 會把 null 和 undefined 當成同一類,所以你可以簡化成一行:

if (name != null) {
  console.log("Hello, " + name)
}

當 name 是 null 或 undefined 時,name != null 都會是 false,一行就能擋掉兩種情況。

用 === 避免型別轉換的意外

如果你不想讓 JavaScript 偷偷轉換型別,要改用 ===(嚴格相等)和 !==(嚴格不相等)。

這兩個運算子會同時比較值和型別,只要型別不同就直接回傳 false,不做任何轉換。

console.log("" == false)  // true(發生型別轉換)
console.log("" === false) // false(型別不同,直接 false)
運算子全名會轉換型別?建議使用?
==寬鬆相等✅ 是謹慎使用
===嚴格相等❌ 否✅ 優先使用
!=寬鬆不等✅ 是謹慎使用
!==嚴格不等❌ 否✅ 優先使用
全名寬鬆相等
會轉換型別?✅ 是
建議使用?謹慎使用
全名嚴格相等
會轉換型別?❌ 否
建議使用?✅ 優先使用
全名寬鬆不等
會轉換型別?✅ 是
建議使用?謹慎使用
全名嚴格不等
會轉換型別?❌ 否
建議使用?✅ 優先使用

小結

這篇文章介紹了 JavaScript 的型別轉換機制,整理三個重點帶走:

  1. 型別轉換是把值從一個型別轉成另一個型別,可以主動呼叫,也可以自動發生。
  2. 自動型別轉換(type coercion) 是 JavaScript 在背後偷偷轉的行為,通常不是你預期的結果,遇到奇怪的輸出時要往這個方向排查。
  3. 預設使用 === 和 !==,除非你確定比較兩側的型別相同,否則避免使用 == 和 !=,可以省去很多除錯的麻煩。
上一篇JavaScript 的 null 和 undefined 是什麼?兩種空值的差異
下一篇JavaScript 短路邏輯運算子:用 || 和 && 寫出更簡潔的程式碼
目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

JavaScript

目錄

  • 什麼是型別轉換?
  • 什麼是自動型別轉換?
  • 8 * null → 0
  • "5" - 1 → 4
  • "5" + 1 → "51"
  • "five" * 2 → NaN
  • == 比較運算子的轉換邏輯
  • null 和 undefined 是特例
  • 用 === 避免型別轉換的意外
  • 小結