JavaScript 中有四個邏輯運算子:||
(OR)、&&
(AND)、!
(NOT)、??
(Nullish Coalescing)。這裡我們將介紹前三個,??
運算子將在下一篇文章中介紹。
儘管它們被稱為「邏輯」,但它們可以應用於任何類型的值,而不僅僅是布林值。它們的結果也可以是任何類型。
讓我們看看詳細資訊。
|| (OR)
「OR」運算子用兩個垂直線符號表示
result = a || b;
在傳統程式設計中,邏輯 OR 僅用於處理布林值。如果它的任何參數為 true
,它會傳回 true
,否則會傳回 false
。
在 JavaScript 中,運算子更為複雜且更強大。但首先,讓我們看看布林值會發生什麼事。
有四種可能的邏輯組合
alert( true || true ); // true
alert( false || true ); // true
alert( true || false ); // true
alert( false || false ); // false
正如我們所見,結果總是 true
,除了兩個運算元都是 false
的情況。
如果運算元不是布林值,它會在評估時轉換為布林值。
例如,數字 1
被視為 true
,數字 0
被視為 false
if (1 || 0) { // works just like if( true || false )
alert( 'truthy!' );
}
大多數時候,OR ||
用於 if
敘述中,以測試給定條件中是否有 任何 條件為 true
。
例如
let hour = 9;
if (hour < 10 || hour > 18) {
alert( 'The office is closed.' );
}
我們可以傳遞更多條件
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // it is the weekend
}
OR "||" 找出第一個真值
上述描述的邏輯有點經典。現在,讓我們引入 JavaScript 的「額外」功能。
延伸演算法的工作方式如下。
給定多個 OR 值
result = value1 || value2 || value3;
OR ||
運算子執行下列動作
- 從左到右評估運算元。
- 對於每個運算元,將其轉換為布林值。如果結果為
true
,則停止並傳回該運算元的原始值。 - 如果所有運算元都已評估(即全部為
false
),則傳回最後一個運算元。
值以其原始形式傳回,不進行轉換。
換句話說,OR ||
鏈會傳回第一個真值,或在找不到真值時傳回最後一個真值。
例如
alert( 1 || 0 ); // 1 (1 is truthy)
alert( null || 1 ); // 1 (1 is the first truthy value)
alert( null || 0 || 1 ); // 1 (the first truthy value)
alert( undefined || null || 0 ); // 0 (all falsy, returns the last value)
與「純粹、經典、僅布林值的 OR」相比,這會導致一些有趣的用法。
-
從變數或表達式清單中取得第一個真值。
例如,我們有
firstName
、lastName
和nickName
變數,全部都是選用的(即可以是未定義或具有假值)。讓我們使用 OR
||
選擇具有資料的那個並顯示它(或在未設定任何內容時顯示"Anonymous"
)let firstName = ""; let lastName = ""; let nickName = "SuperCoder"; alert( firstName || lastName || nickName || "Anonymous"); // SuperCoder
如果所有變數都是假值,則會顯示
"Anonymous"
。 -
短路評估。
OR
||
運算子的另一個特點是所謂的「短路」評估。這表示
||
會處理其參數,直到達到第一個真值,然後立即傳回該值,甚至不會觸及其他參數。如果運算元不只是值,而是具有副作用的表達式(例如變數指定或函式呼叫),則此功能的重要性就顯而易見。
在以下範例中,只會列印第二個訊息
true || alert("not printed"); false || alert("printed");
在第一行中,OR
||
運算子在看到true
時會立即停止評估,因此不會執行alert
。有時,人們會使用此功能來執行命令,前提是左邊條件為假。
&& (AND)
AND 運算子用兩個連字號 &&
表示
result = a && b;
在傳統程式設計中,如果兩個運算元都為真,AND 會傳回 true
,否則傳回 false
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
使用 if
的範例
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'The time is 12:30' );
}
就像 OR 一樣,任何值都可以作為 AND 的運算元
if (1 && 0) { // evaluated as true && false
alert( "won't work, because the result is falsy" );
}
AND “&&” 會找出第一個假值
給定多個 AND 值
result = value1 && value2 && value3;
AND &&
運算子會執行下列動作
- 從左到右評估運算元。
- 針對每個運算元,將其轉換為布林值。如果結果為
false
,則停止並傳回該運算元的原始值。 - 如果所有運算元都已評估(即所有運算元都為真),則傳回最後一個運算元。
換句話說,AND 會傳回第一個假值,或者如果沒有找到假值,則傳回最後一個值。
上述規則類似於 OR。不同之處在於,AND 傳回第一個假值,而 OR 傳回第一個真值。
範例
// if the first operand is truthy,
// AND returns the second operand:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// if the first operand is falsy,
// AND returns it. The second operand is ignored
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
我們也可以連續傳遞多個值。看看第一個假值是如何傳回的
alert( 1 && 2 && null && 3 ); // null
當所有值都為真時,會傳回最後一個值
alert( 1 && 2 && 3 ); // 3, the last one
&&
的優先權高於 OR ||
AND &&
運算子的優先權高於 OR ||
。
因此,程式碼 a && b || c && d
基本上與 &&
運算式放在括號中相同:(a && b) || (c && d)
。
||
或 &&
取代 if
有時,人們會使用 AND &&
運算子作為「撰寫 if
的較短方式」。
例如
let x = 1;
(x > 0) && alert( 'Greater than zero!' );
&&
右邊的動作只會在評估到達時執行。也就是說,只有當 (x > 0)
為真時才會執行。
因此,我們基本上有一個類比
let x = 1;
if (x > 0) alert( 'Greater than zero!' );
儘管使用 &&
的變體看起來較短,但 if
較為明顯,且傾向於更易於閱讀。因此,我們建議針對其目的使用每個結構:如果我們想要 if
,就使用 if
;如果我們想要 AND,就使用 &&
。
!(非)
布林非運算子以驚嘆號 !
表示。
語法非常簡單
result = !value;
運算子接受單一參數並執行下列動作
- 將運算元轉換為布林類型:
true/false
。 - 傳回反向值。
例如
alert( !true ); // false
alert( !0 ); // true
有時會使用雙非 !!
來將值轉換為布林類型
alert( !!"non-empty string" ); // true
alert( !!null ); // false
也就是說,第一個非將值轉換為布林並傳回反向值,而第二個非再次反向值。最後,我們得到一個純粹的值轉布林轉換。
有一個稍微冗長的作法可以執行相同的事情,也就是內建的 布林
函式
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
非 !
的優先權高於所有邏輯運算子,因此它總是會先執行,在 &&
或 ||
之前。
留言
<code>
標籤,對於多行程式碼,請將它們包覆在<pre>
標籤中,對於超過 10 行的程式碼,請使用沙盒 (plnkr、jsbin、codepen…)