天天看點

JavaScript 邏輯且(&&)和邏輯或(||)的妙用

簡單運用

邏輯且(&&):左右必須都滿足 true 才傳回 true;邏輯或(||):左右其中一個滿足 true 就傳回 true。

這樣簡單的運用是整體傳回一個布爾值,适合在語句判斷的時候用:

let user = localStorage.getItem("user");

if (user && user.age > 10) {
  // ...
}
           

當 user 存在時(即 true),且 user 的 age 字段大于 10,

if

語句得到的布爾值才是 true,第一個條件句才執行。

進階運用

上面都是邏輯且和邏輯或的簡單使用,其實它們大有用處,還能簡化代碼。運算符操作的對象稱之為操作數(Operand)。

邏輯且

左邊操作數結果 右邊操作數結果 執行的操作數 整體結果
true true true
false true false
true false false
false false false

根據上表格得出一個結論:

  1. 如果左操作數的結果是一個 true,就執行右操作數。
  2. 如果左操作數的結果是一個 false,就執行左操作數。

總而言之,邏輯且(&&)隻要遇到 false,就執行這個操作數,而另一個操作數直接忽略。

假設傳入了回調函數就執行,否則跳過不執行。一般想到的是用 if 條件語句,或者三元運算符簡化 if 條件語句。利用邏輯且(&&)的特性可以進一步簡化代碼:

function fun(callback) {
  // ...
  callback && callback();
}

fun(() => console.log("execute callback function.")); // 控制台列印了字元串!
fun(); // 什麼也沒有發生!
           

邏輯或

左邊操作數結果 右邊操作數結果 執行的操作數 整體結果
true true true
false true true
true false true
false false false

根據上表得出結論:

  1. 如果左操作數的結果是一個 true,就執行左操作數。
  2. 如果左操作數的結果是一個 false,就執行右操作數。

簡而言之,邏輯或(||)一旦遇到操作數的結果是 true,就執行這個操作數,而另一個操作數直接忽略不執行。

邏輯且提供預設值

if 語句提供預設值:

function fun(x) {
  if (!x) {
    x = "default value";
  }
  console.log(x);
}

fun(undefined); // "default value"
fun("inject a value"); // inject a value
           

邏輯且提供預設值:

function fun(x) {
  x = !x && "default value";
  console.log(x);
}

fun(undefined); // "default value"
fun("inject a value"); // false
           

對 x 判斷是否為假值,如果是假值就應該走第二個預設值的操作數。假如 x 是 false(假值),那麼就執行第一個操作數,依舊傳回假值,是以對其取反,走第二個操作數,傳回預設值。當傳入的 x 是真值,由于前面的問題,真值被取反得假值,而傳回了第一個操作數的結果,即 false 布爾值。

可能是我沒有想到更好的方式,是以,我認為邏輯且(&&)不适合用來提供預設值。

邏輯或提供預設值

實際上邏輯或提供預設值才是等價于上面說到的 if 語句提供預設值的邏輯:

function fun(x) {
  x = x || "default value";
  console.log(x);
}

fun(undefined); // "default value"
fun("inject a value"); // inject a value
           

是以,我認為邏輯或(||)适合提供預設值這一工作。

比較兩者

邏輯或(||)的用處比邏輯且的用途廣。前面說到,邏輯且(&&)不适合提供預設值,而邏輯或(||)既适合提供預設值,也适合做決定是否執行回調函數等一些列工作。

改造進階運用 - 邏輯且的例子代碼:

function fun(callback) {
  // ...
  !callback || callback();
}

fun(() => console.log("execute callback function.")); // 控制台列印了字元串!
fun(); // 什麼也沒有發生!
           

更多邏輯或的例子

屬性的預設值

setTitle(options.title || 'untitled');
           

在給函數傳遞參數時,如果 options.title 是 null 或者其他之類的假值,就提供字元串

untitled

給函數。

函數結果的預設值

function countOccurrences(regex, str) {
  return (str.match(regex) || []).length;
}
           

match()

方法會傳回一個數組或 null。得益于邏輯或(||),在後一種請看下可以設定一個預設值。是以,在這兩種情況下你都可以安全地通路 length 屬性。

繼續閱讀