為什麼 JavaScript 的 || 和 && 不只是布林運算?——從「短路求值」談起

更新日期: 2025 年 4 月 21 日

在多數程式語言中,邏輯運算子(如 ||&&)的用途是用來處理「條件判斷」,它們的最終結果通常是布林值 truefalse

if (a > 0 && b > 0) {
  // 條件為真才執行
}

然而在 JavaScript 中,||&& 有一個更靈活且強大的設計——它們不一定只回傳布林值,這背後的關鍵就在於:「短路求值(short-circuit evaluation)」。

什麼是短路求值?為何這樣設計?

短路求值(Short-circuit evaluation)是什麼?

短路求值是一種在邏輯運算中常見的效能優化技巧

它的核心思想是:

當運算途中已經能決定結果,就不再繼續計算剩下的部分。

換句話說,整個邏輯表達式「不一定要全部算完」,只要途中某一個條件足以判斷整體結果,就可以直接停下來。

這不只是一種偷懶的寫法,而是源自於電腦科學中的效率設計原則

💡 舉個生活例子

假設你早上起床,會根據兩個條件決定要不要帶傘:

  • 今天會下雨?
  • 帶不帶傘?

如果第一個條件就已經是「不會下雨」,你根本就不需要去判斷第二個條件,因為「帶不帶傘」這件事已經有答案了。

這就是短路求值的邏輯思維:遇到足夠資訊,後面就不浪費力氣。

為什麼叫做「Short-circuit」?

這個詞源自於電子電路的運作邏輯

在電路設計中,「circuit」指的是電流流動的路徑,而「short-circuit(短路)」則是當電流發現一條更快、更短、更直接的路徑可以走,就會避開原本完整的路線,從而提早結束整個迴路。

這種「繞過冗長流程、直接產出結果」的思想,被借用來形容程式語言中邏輯運算的這種提早中斷行為。

在程式中,「短路」不是壞事,而是一種節省計算資源的好事


JavaScript 中的短路行為:不只邏輯,更是值的選擇機制

在 JavaScript 中,邏輯運算子 ||(邏輯或)與 &&(邏輯與)不只是判斷條件是否為 truefalse它們還會根據運算過程中的「第一個足以決定結果的值」直接回傳該值本身

這種設計,讓 JavaScript 的邏輯運算子具有高度的彈性與表現力,能夠兼顧條件控制與資料處理。

||(邏輯或 OR)

🔹 邏輯意義:

只要「其中一個」為真,整體就為真。

🔹 短路邏輯:

當左側的值為 truthy(可視為「成立」的值),就會直接回傳該值,不再理會右邊的運算。

🔹 回傳行為:

  • 若左邊為 truthy ➜ 回傳左邊的值
  • 否則 ➜ 回傳右邊的值(不管是否為 truthy)

🔍 範例:

console.log("A" || "B");  // "A":左邊已經成立,不需看右邊
console.log("" || "B");   // "B":左邊是 falsy,回傳右邊
console.log(null || 0 || "Hello"); // "Hello":前兩個都 falsy,回傳第三個

這個行為常被用來提供預設值防止空值錯誤

✅ 補充:falsy 值

在 JavaScript 中,被判定為 false 的值稱為 falsy 值。這些值在布林上下文中,會被自動轉換為布林值 false。常見的 falsy 值包括:

NaN – 表示非數字值(Not-a-Number)

false – 布林值 false

0 – 數字零

-0 – 負零

0n – BigInt 的零,這是一種能夠表示非常大整數的數據類型

” ” 或 ‘ ‘ 或 “ “ – 空的字符串值(不管是使用雙引號、單引號還是反引號)

null – 表示無值

undefined – 表示未定義的值

&&(邏輯與 AND)

🔹 邏輯意義:

只有「兩者都為真」,整體才為真。

🔹 短路邏輯:

當左側的值為 falsy(可視為「不成立」的值),就會直接回傳該值,不再執行右邊。

🔹 回傳行為:

  • 若左邊為 falsy ➜ 回傳左邊的值
  • 否則 ➜ 回傳右邊的值

🔍 範例:

console.log("A" && "B");  // "B":左邊為真,繼續運算並回傳右邊
console.log("" && "B");   // "":左邊為假,短路回傳左邊
console.log(1 && 0 && "C"); // 0:第一個 truthy,第二個 falsy,短路

這個行為常被用來做條件執行防止不必要的操作

短路求值的實用應用:讓程式更簡潔與安全

預設值處理(使用 ||

當一個變數可能為 nullundefined 或空值時,我們可以用 || 提供一個「退路」:

const username = inputName || "訪客";

這等於說:

  • inputName 是有效的(truthy) ➜ 使用它
  • 否則 ➜ 回傳 "訪客" 當作替代值

✅ 用途:用於表單、設定值、顯示畫面等場景,是處理空值的最佳寫法。

條件執行(使用 &&

&& 可以拿來讓某段程式碼「只有在符合條件時才執行」,取代傳統 if 寫法。

isLoggedIn && showDashboard();

這等於:

  • isLoggedIn 為真 ➜ 執行 showDashboard()
  • 若為假 ➜ 整段不執行,無錯誤也無副作用

✅ 用途:執行函式、渲染畫面、觸發副作用時,能簡化條件邏輯。

補充觀念:什麼是「退路(Fallback)」?

在程式語言中,「退路」是一種預備方案。當主要路線失效或不可用時,就切換到備用值或備用行為

短路求值就是這種「退路設計」最經典的語法手段。

🔍 範例:

const lang = userSetting.lang || "en";
// 若 userSetting.lang 沒有被設定 ➜ 自動退回英文版

這種設計有三大優點:

  1. 簡潔:不需多餘的 if三元運算子
  2. 容錯:避免 null 或 undefined 導致程式錯誤
  3. 彈性:便於快速切換預設行為

短路求值 + 優先順序:決定「誰先算」與「何時停」

前面我們了解了 ||&& 各自的短路行為,但在實際應用中,兩者往往混合出現於同一個表達式中

這時候,就需要了解另一個關鍵概念:運算子的優先順序(Operator Precedence)

優先順序是什麼?

當一個表達式中有多個運算子時,JavaScript 必須決定哪個運算子要先被執行

就像數學中「先乘除後加減」,JavaScript 也有屬於自己的優先順序。

&& 優先於 ||

在 JavaScript 中,邏輯運算子的優先順序如下(數字越高,優先級越高):

運算子名稱優先順序結合性
!邏輯非17右至左(right-to-left)
&&邏輯與6左至右(left-to-right)
||邏輯或5左至右(left-to-right)

因此當 &&|| 同時出現在一個表達式中時,會先執行 &&,再執行 ||

優先順序 + 短路求值 的結合流程

這兩個機制搭配時,運作順序會是:

1️⃣ 先依據優先順序確定計算順序
2️⃣ 每個子運算依照短路規則進行,提早停止不必要的計算

🧪 範例解析

const result = '' && 'World' || 'Goodbye';

🔹 依照優先順序,先算 '' && 'World'

  • '' 是 falsy → 直接回傳 '',不算右邊 'World'(短路)

🔹 接著變成:'' || 'Goodbye'

  • '' 是 falsy → 回傳 'Goodbye'

最終結果為: "Goodbye"

🧪 再看一個混合例子:

const result = 'Hi' || 0 && 'Bye';

🔹 依照優先順序,先算 0 && 'Bye'

  • 0 是 falsy → 短路回傳 0

🔹 接著變成:'Hi' || 0

  • 'Hi' 是 truthy → 回傳 'Hi'

結果是: "Hi"

小技巧:不確定就加括號

在條件邏輯比較複雜、含有多個邏輯運算子時,加上括號可以幫助你:

  • 清楚控制運算順序
  • 提高可讀性
  • 避免誤會與 bug
// 不推薦(容易搞錯)
const result = user && isActive || isGuest;

// 推薦(邏輯明確)
const result = (user && isActive) || isGuest;

✅ 小結:兩個機制如何分工合作?

機制角色重點行為
運算子優先順序誰先被處理&& 優先於 `
短路求值要不要處理右邊&&:左邊為假就不繼續;`

如果說優先順序是誰先上場,那麼短路求值就是誰先下班

這兩個觀念一起掌握,你就能完全理解 JavaScript 中邏輯運算的真實行為!

Similar Posts