JavaScript 簡易指南:掌握 || 和 && 運算子的妙用

更新日期: 2024 年 9 月 14 日

本文將從基礎出發,逐步引導你了解 || 和 && 運算子的基本概念、它們在實際開發中的應用,以及如何利用它們來簡化和優化你的代碼。

無論你是剛開始學習 JavaScript 的新手,還是希望加深對這些運算子理解的資深開發者,本文都將提供實用的資訊和代碼示例,幫助你更好地掌握 || 和 && 的妙用。

邏輯運算子基本介紹

在 JavaScript 中,「邏輯運算子」扮演著決定程式流程的關鍵角色。

這一部分將深入探討兩個基本但強大的邏輯運算子:|| (或) 和 && (且)。

這些運算子用於比較布林值,並根據這些比較產生新的布林結果。

了解這些運算子的基本運作原理,對於編寫更有效、更可讀的代碼至關重要。

|| (或) 運算子

|| 運算子在 JavaScript 中代表「或」的概念。

當它連接兩個表達式時,如果至少一個表達式評估為真(true),則整個表達式的結果為真。

如果兩個表達式都評估為假(false),則結果為假。

|| 運算子常用於設定預設值或在多個條件中尋找至少一個真值的情況。

基本用法示例:

let a = false || true; 
let b = false || false; 

console.log(a);

// 回傳:
// true

console.log(b);

// 回傳:
// false

這種運算子非常適合於,需要從多個可能的值中,選擇一個有效值時使用。

&& (且) 運算子

相對於 || 運算子,&& 運算子代表「且」的概念。

它要求所有連接的表達式都評估為真,整個表達式的結果才會是真。

如果任何一個表達式評估為假,則結果為假。

&& 運算子是用來確保多個條件同時滿足的理想選擇。

基本用法示例:

let a = true && true; 
let b = true && false; 

console.log(a);

// 回傳:
// true

console.log(b);

// 回傳:
// false

短路求值

在許多程式語言中,邏輯運算子確實是用來產生布林值(true 或 false)的結果。

然而,JavaScript 的 || 和 && 邏輯運算子有一個特別的行為,稱為「短路求值」(Short-circuit evaluation),這讓它們的行為與許多其他語言不同。

|| 運算子

對於 ||(或)運算子,JavaScript 會從左到右評估運算元,並返回第一個 truthy 值。

如果所有運算元都是 falsy,則返回最後一個運算元的值。

這意味著結果並不限於布林值,它可以是任何類型的值。

補充:falsy 值

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

  1. false – 布林值 false
  2. 0 – 數字零
  3. -0 – 負零
  4. 0n – BigInt 的零,這是一種能夠表示非常大整數的數據類型
  5. ” ” 或 ‘ ‘ 或 “ “ – 空的字符串值(不管是使用雙引號、單引號還是反引號)
  6. null – 表示無值
  7. undefined – 表示未定義的值
  8. NaN – 表示非數字值(Not-a-Number)

當這些值被用在需要布林值的表達式中(例如 if 條件語句或邏輯運算子中)時,它們會被自動轉換為 false。

讓我們看一個更簡單的例子,以展示 || 運算子如何從左至右評估運算元,並返回第一個 truthy 值,或在所有運算元都是 falsy 時返回最後一個運算元的值。

let result;

// 情況 1:第一個運算元為 "truthy"
result = 'Hello' || 'World';
console.log(result);  

// 輸出: 
// 'Hello'


// 情況 2:第一個運算元為 "falsy",第二個運算元為 "truthy"
result = '' || 'World';
console.log(result);  

// 輸出: 
// 'World'


// 情況 3:兩個運算元都是 "falsy"
result = '' || false;
console.log(result);  

// 輸出: 
// false


// 情況 4:第一個運算元為 "falsy",第二個運算元為 "truthy"
result = 0 || 'Hello';
console.log(result);  

// 輸出: 
// 'Hello'

在這個例子中,我們看到了四種不同的情況:

情況一

當第一個運算元是 truthy(非空字符串 Hello)時,|| 運算子立即返回這個運算元的值,因此 result 是 Hello。

情況二

當第一個運算元是 falsy(空字符串 ‘ ‘)而第二個運算元是 truthy(非空字符串 World)時,|| 運算子返回第二個運算元的值,因此 result 是 World。

情況三

當兩個運算元都是 falsy(空字符串 ‘ ‘ 和 false)時,|| 運算子返回最後一個運算元的值,即使它是 falsy,因此 result 是 false。

情況四

當第一個運算元是 falsy(0)而第二個運算元是 truthy(非空字符串 Hello)時,情況與情況 2 相同,因此 result 是 ‘Hello’。

這個簡單的例子清楚地展示了 || 運算子如何工作,特別是它如何處理 truthy 和 falsy 值以及返回哪個運算元的值。

這使得 || 運算子非常適合於設定預設值,和進行簡單的條件選擇。

&& 運算子

類似地,&&(且)運算子返回第一個 falsy 值的運算元。

如果所有運算元都是 truthy,則返回最後一個運算元的值。因此,&& 的結果也不僅僅是布林值。

例如,true && Yes 會返回 Yes,因為所有運算元都是 truthy,且 Yes 是最後一個運算元。

讓我們透過一個簡單的例子來展示 && 運算子如何工作,即它是如何返回第一個 falsy 值的運算元,或者在所有運算元都是 truthy 時返回最後一個運算元的值。

let result;

// 情況 1:兩個運算元都是 "truthy"
result = 'Hello' && 'World';
console.log(result);  

// 輸出: 
// 'World'


// 情況 2:第一個運算元是 "falsy"
result = '' && 'World';
console.log(result);  

// 輸出: 
// ''


// 情況 3:第二個運算元是 "falsy"
result = 'Hello' && 0;
console.log(result);  

// 輸出: 
// 0


// 情況 4:兩個運算元都是 "falsy"
result = false && NaN;
console.log(result);  

// 輸出: 
// false

在這個例子中,我們看到了四種不同的情況:

情況一

當兩個運算元都是 truthy(非空字符串 Hello 和 World)時,&& 運算子返回最後一個運算元的值,因此 result 是 World。

情況二

當第一個運算元是 falsy(空字符串 ‘ ‘)時,&& 運算子立即返回這個運算元的值,因此 result 是 ‘ ‘,而不會評估第二個運算元

情況三

當第二個運算元是 falsy(數字 0)而第一個運算元是 truthy 時,&& 運算子返回第二個運算元的值,因此 result 是 0。

情況四

當兩個運算元都是 falsy(布林值 false 和 NaN)時,&& 運算子返回第一個運算元的值(因為它是第一個被評估為 falsy 的運算元),因此 result 是 false。

這個簡單的例子清楚地展示了 && 運算子的行為:它按順序評估運算元,並在遇到第一個 falsy 值時停止評估,返回該值。

或者在所有運算元都是 truthy 時,返回最後一個運算元的值。

這種行為使得 && 運算子非常適合進行連續的條件檢定。

運算子的優先順率與評估順序

當一行代碼中同時出現 && 和 || 運算子時,理解它們的「評估順序」與「運算優先級」是非常重要的。

想像您在閱讀一本書,從左到右閱讀文字(這代表「從左至右評估」的評估順序),同時您遇到了帶有標點的句子。

在這個過程中,標點符號(比如逗號、句號)告訴您如何理解句子中的不同部分,哪些詞或短語是更緊密地連接在一起的(這代表「運算符優先級」的概念)。

  • 從左到右閱讀:您從句子的開始讀到結束,這就像在程式中從左到右,逐個檢查每個元素或運算符。
  • 標點的優先級:雖然您從左到右閱讀,但標點符號會影響您理解句子的方式。例如,括號內的短語會先被理解為一個整體,這就像在編程中優先計算括號內的表達式。

相同概念,套用運算子的編碼邏輯:

  • 從左到右評估:這是程序處理表達式的基本順序,類似於您閱讀句子的方式。
  • 運算符優先級:這告訴程序在處理表達式時哪些部分應該被視為更緊密連接的整體,即使它們在文本上可能不是緊鄰的。就像標點符號幫助您理解句子結構一樣,運算符優先級幫助程序正確理解表達式的結構。

讓我們用一個簡單的例子來解釋這個概念:

let result = true || false && false;

當我們面對這段代碼,我們需要根據運算符優先級和從左至右的評估規則來解讀其運作過程。

運算符優先級與評估規則

  1. 運算符優先級:在 JavaScript 中,&& 運算符的優先級高於 || 運算符。這意味著在沒有使用括號明確指定順序的情況下,包含 && 的表達式(及其兩邊的表達式)會被首先考慮計算。
  2. 從左至右的評估:儘管 && 擁有較高的優先級,整個表達式的評估過程仍然會從左側開始。首先檢查 || 運算符左側的值(在此例中為 true),接著根據 || 運算符的短路邏輯來決定是否需要評估右側。

代碼解釋

  • 在表達式 true || false && false 中,即使 && 的優先級更高,整個表達式的評估仍從左側開始。
  • 首先對 true || … 進行評估。由於 || 運算符的短路特性,若其左邊是 true,則整個表達式的結果就確定為 true,不需再計算右邊的表達式。
  • 因此,即便 false && false 在邏輯上會首先被視為一個單元(若需要計算的話),但在這個特定情況下,由於 || 左側已是 true,所以 false && false 部分不會被執行。

最終結果為 true,因為 || 運算符左側的 true 已決定了整個表達式的結果,無需進一步評估 && 部分。

&& 與 || 運算子

我們將在此基礎上探討當 || 和 && 運算子同時出現時,不同情況下的結果變化。

// 情況 1:兩個運算元都是 "truthy"
result = 'Hello' && 'World' || 'Goodbye';
console.log(result);  

// 輸出: 
// 'World'



// 情況 2:第一個運算元是 "falsy"
result = '' && 'World' || 'Goodbye';
console.log(result);  

// 輸出: 
// 'Goodbye'


// 情況 3:第二個運算元是 "falsy"
result = 'Hello' && 0 || 'Goodbye';
console.log(result);  

// 輸出: 
// 'Goodbye'


// 情況 4:兩個運算元都是 "falsy"
result = false && NaN || 'Goodbye';
console.log(result); 
 
// 輸出: 
//'Goodbye'

在這個例子中,我們看到了四種不同的情況:

情況一

由於 Hello 和 World 都是 truthy,所以 && 運算返回 World。

接下來,World || Goodbye 中,由於 World 已經是 truthy,|| 運算直接返回 World,後面的 Goodbye 不會被評估。

情況二

‘ ‘ && ‘World’ 中第一個運算元是 falsy,因此 && 運算直接返回 ‘ ‘,且 World 不會被評估。

然後,’ ‘ || Goodbye 執行,由於第一個運算元是 falsy,|| 運算返回第二個運算元 Goodbye

情況三

Hello && 0 中,雖然 Hello 是 truthy,但 && 運算會返回第二個運算元 0(因為它是 falsy)。

接著,0 || Goodbye 執行,|| 運算返回 Goodbye,因為第一個運算元是 falsy

情況四

false && NaN 中,false 是 falsy,因此 && 運算直接返回 false,NaN 不會被評估。

隨後,false || Goodbye 執行,由於第一個運算元是 falsy,|| 運算返回 Goodbye

透過上述例子,我們可以看到在不同情況下當 || 和 && 運算子同時出現時,表達式的計算結果如何受到運算元 truthy 和 falsy 狀態的影響。

運算子進階應用與實際案例

在掌握了 JavaScript 中 || (或) 和 && (且) 運算子的基本概念後,我們現在轉向它們的進階應用。

這些運算子的真正力量不僅在於進行簡單的真假判斷,而且在於它們能夠在更複雜的場景中,提供靈活的判斷條件設定。

利用 || 運算子進行預設值設定

|| 運算子非常適合用於設定函數參數的預設值。

在 ES6 之前,JavaScript 開發者經常使用 || 來處理未傳遞參數或參數為 undefined 的情況。

// 代碼示例:設置預設值:

function greet(name) {
  name = name || 'Guest';
  console.log('Hello, ' + name + '!');
}

greet('Alice'); 

// 輸出:
// Hello, Alice!


greet();        

// 輸出:
// Hello, Guest!

在這個例子中,如果沒有為 greet 函數提供 name 參數,或者 name 參數為 undefined,則 name 會被設置為 Guest。

利用 && 運算子進行條件執行

&& 運算子常被用於條件執行——僅當特定條件為真時,才執行某些操作。

這種模式特別有用於需要先檢查一個或多個條件是否滿足,然後才能安全執行後續操作的情況。

// 代碼示例:條件性執行函數

function maybeInitialize() {
  console.log('Initialization complete.');
}

let isInitialized = false;

// 只有在 isInitialized 為 false 時才初始化
isInitialized || (isInitialized = true) && maybeInitialize();

// 輸出:Initialization complete.

在這個例子中,我們使用 && 運算子來確保 maybeInitialize 函數僅在 isInitialized 為 false 時被調用。

一旦初始化完成,isInitialized 變為 true,進一步的初始化調用就會被跳過。

結論

在這篇文章中,我們深入探討了 JavaScript 中兩個基本但強大的邏輯運算子——|| (或) 和 && (且)。

從它們的基本概念到進階應用,再到實用技巧,本文提供一個全面的指南,幫助開發者不僅理解這些運算子的工作原理,還能夠在日常開發中靈活運用它們。

Similar Posts