跳至主要内容

條件判斷

9/1/2023 發布

條件判斷是控制程式運行流程的關鍵,寫得好就上天堂,寫不好就波動拳。

if-else

依照判斷區間的 true / false 來決定是否執行:

let a = 1;

if (a > 0) {
console.log("a 大於 0"); // true 會執行
}

能判別為 true 的叫做真值(truthy),判別為 false 的則是假值(falsy),
除了大於、小於等等的比較結果,也經常用在判定某些變數、物件存不存在,
以下都是會判定為 false 的假值:

  • undefined
  • 0
  • ''(空字串)
  • null
  • NaN
if (message) {
console.log("有訊息:", message);
} else {
// 訊息有可能不存在,會是空字串、undefined、null 等等的值
console.log("沒有訊息");
}

switch

switch 是拿傳入的值和 case 的值比較是否嚴格相等,來決定是否執行該 case,
和 case 的條件成立與否無關:

let wallet = 300;

switch (wallet) {
case wallet > 500:
console.log("給我一瓶酒再給我一支菸");
break;
case wallet > 100:
console.log("因為錢就是我快樂的泉源");
break;
default:
console.log("把愛勇氣希望都賣了能換來多少錢");
}

// 會印出 '把愛勇氣希望都賣了能換來多少錢'

wallet < 100 雖然條件成立,但這個判斷式實際上代表 true 這個值,
所以程式碼運行時是在比較 walletcase 的值是否相等,
wallet 的 300 並不嚴格相等於 true,也就沒有進到 wallet > 100 這個 case,
最後執行的是 default 的內容。

想進到 case,只要把 switch(wallet) 改成 switch(true) 即可,
但一般不這麼做是因為不符合語意

需要列舉出所有純值的結果時,switch 會比較好讀,也可以避免過多巢狀結構。
而需要同時符合多個條件時,if-else 會是比較好閱讀的:

// 需要多重條件判斷就用 if-else
if (bmi > 35) {
console.log("重度肥配");
} else if (bmi < 35 && bmi >= 30) {
console.log("中度肥胖");
}

// 有明確可以列舉的 case
switch (option) {
case "A":
console.log("選項 A 不是答案");
break;
case "B":
console.log("選項 B 不是答案");
break;
case "C":
console.log("選項 C 是正確答案");
break;
default:
console.log("你怎麼沒選答案");
}

三元運算

如果需要針對某個狀態的 true/false 接收對應的內容,可以用三元運算簡化程式碼長度:

let result = getData();

// if else 的寫法
if (result) {
console.log("有資料");
} else {
console.log("沒資料");
}

// 三元運算的寫法
console.log(result ? "有資料" : "沒資料");

也可以像 if-else 寫一些程式碼進去執行,如下面範例,
但個人覺得三元運算單純用在取值就好,否則可讀性會有點差:

let message = getMessage();

// 不好的寫法
message ? console.log("有訊息") : console.log("沒訊息");

// 好一點的寫法
console.log(message ? "有訊息" : "沒訊息");

// 這樣也可以
let message = getMessage() ? "有訊息" : "沒訊息";
console.log(message);

短路取值

可以組合多個值並回傳一個真假值,經常和 if 一起使用,做多重條件的判斷。

OR ||

有一邊為 true 就成立
兩邊都是 true 時 ,只會提前返回第一個真值的「內容」,不會進到後面的判斷,
如果真值本身就是我們需要的內容(非空的字串、非零的數字等等)也可以用 OR 取值。

下面範例是假設執行 getData() 會得到一個陣列資料,
如果沒有取到資料就賦予一個空陣列給 data:

// 假設 getData 會回傳陣列或 null
// 用 || 可以進行判斷後再賦予值
let data = getData() || [];

AND &&

兩邊為 true 才成立,回傳的是後面的值。
如果兩邊都是 false 時,在第一個 false 就會提前返回,
null && undefined 會回傳 null

console.log("有東西" && "真的有東西"); // "真的有東西"
console.log(null && "有東西"); // null
console.log(null && undefined); // null

AND 的邏輯是要兩邊都要判斷,因此兩邊都是 true 就代表已經做到第二個值的檢查了,
所以回傳的會是後面那一個值。

空值合併運算子 ??

第一個值是 nullundefined 時回傳右邊的值,
0 或是空字串等其他假值不會判斷到後面:

console.log(null ?? "有東西"); // '有東西'
console.log("" ?? "這裡也有東西"); // ''

例外排除

刷題時很常遇到不合法的值忘記要排除,
如果在第一個條件就過濾掉例外值,就可以跳過一連串的判斷,
增加一些可讀性與效能:

function showBodyCondition(bmi) {
// 把不合法的條件移到第一個
if (isNaN(bmi) || typeof bmi !== "number") {
console.log("請輸入合法的數字");
} else if (bmi < 17.5) {
console.log("過輕");
}
//...
}

early return 也是很常使用的技巧,
在函式內只要執行到 return 就會脫離函式,後面的程式碼就不會繼續執行,
如下面範例,showPokemonData 一開始就先判斷資料是否還在讀取或者資料不存在:

function showPokemonData(data) {
if (isLoading || !data) {
return;
}

console.log(data);
}

參考資料