iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
自我挑戰組

寫程式帶給我的無形快樂系列 第 11

寫出好讀好寫的 JS (下)

  • 分享至 

  • xImage
  •  

if...else 很好用
但當它變得複雜,變得像洋蔥一層又一層的時候... 很痛苦

如果要寫出好讀好寫的 JS,學會怎麼簡化 if...else,是很重要的課題!

題外話:
還記得曾經遇過一個客戶,請工程師協助調整功能
不論我們怎麼解釋....調整這個需求需要花時間

卻得到一句 "不就是多加一個 if...else 嗎"

以下範例摘自5 Tips to Write Better Conditionals in JavaScript 介紹五種可以讓條件式寫的更優雅的方法


利用 Array.includes 判斷多種條件

function test(fruit) {
  if (fruit == 'apple' || fruit == 'strawberry') {
    console.log('red');
  }
}

當今天如果條件式裡只有一個條件 if (fruit == 'apple'), 還可以,沒有問題

但如果出現了第二個條件 if (fruit == 'apple' || fruit == 'strawberry'),就可以考慮改寫了

原因是: fruit 變數可能會重複寫很多次,例如 fruit == 'xxxx' 會一直往後接下去

利用 Array.includes ,判斷某元素是否有出現在陣列中

重構後:

function test(fruit) {
  // 將條件寫在 Array 中
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  if (redFruits.includes(fruit)) {
    console.log('red');
  }
}

之後要新增水果,直接異動 redFruits 就好,不用寫在 if 裡!


減少 if 巢狀,早早 Return

延續上面的例子

  1. 如果沒有傳入 fruit --> throw Error
  2. 傳入數量,如果超過10,印出 太多太多
function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];

  // 第一層: 是否有 fruit 存在
  if (fruit) {
    // 第二層: 是否為紅色的水果
    if (redFruits.includes(fruit)) {
      console.log('red');

      // 第三層: 是否超過目標數量(10)
      if (quantity > 10) {
        console.log('太多太多');
      }
    }
  } else {
    throw new Error('水果咧!');
  }
}

// 執行結果
test(null); // error: 水果咧
test('apple'); // print: red
test('apple', 20); // print: red, 太多太多
  1. 總共有三層 if --> 不好閱讀
  2. 程式碼是由上往下閱讀 --> 看到最後才知道 fruit 沒有值的結果

重構成:

function test(fruit, quantity) {
  const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
  
  // 把驗證 fruit 有值與否寫在最前面 --> 驗證失敗 --> throw error (後面的判斷就可以不用看了)
  if (!fruit) throw new Error('水果咧'); // 第一關: throw error early
  if (!redFruits.includes(fruit)) return; // 第二關: 當水果不在 redFruits 中 --> Return

  console.log('red');

  // 第三關: 數量是否大於 10 
  if (quantity > 10) {
    console.log('太多太多');
  }
}

『 透過 Early Return 來控制流程,減少巢狀的寫法 』


善用 Function 參數預設值

function test(fruit, quantity) {
  if (!fruit) return;
  const q = quantity || 1; // 數量預設值是 1

  console.log(`We have ${q} ${fruit}!`);
}

//test results
test('banana'); // We have 1 banana!
test('apple', 2); // We have 2 apple!

還可以更好的地方--> q 這個變數可以省略宣告

function test(fruit, quantity = 1) { // 預設值直接寫在 parameter 中
  if (!fruit) return;
  console.log(`We have ${quantity} ${fruit}!`);
}

//test results
test('banana'); // We have 1 banana!
test('apple', 2); // We have 2 apple!

利用 Object 來取代 Switch

假設想要依不同的顏色印出對應的水果

function test(color) {
  // 利用 switch case
  switch (color) {
    case 'red':
      return ['apple', 'strawberry'];
    case 'yellow':
      return ['banana', 'pineapple'];
    case 'purple':
      return ['grape', 'plum'];
    default:
      return [];
  }
}

//test results
test(null); // []
test('yellow'); // ['banana', 'pineapple']

觀察可以發現程式碼重複性很高

重構成:

// 利用物件的方式來儲存資料,並用顏色當做 key 值
  const fruitColor = {
    red: ['apple', 'strawberry'],
    yellow: ['banana', 'pineapple'],
    purple: ['grape', 'plum']
  };

function test(color) {
  return fruitColor[color] || [];
}

善用 Array.everyArray.some 來檢查 item

檢查 fruits 中的所有水果是否都為紅色

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
  ];

function test() {
  let isAllRed = true;

  // condition: 所有項目都必須為紅色
  for (let f of fruits) {
    if (!isAllRed) break;
    isAllRed = (f.color == 'red');
  }
  console.log(isAllRed); // false
}

可以利用 Array.every 來重構成:

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
  ];

function test() {
  const isAllRed = fruits.every(f => f.color == 'red');
  console.log(isAllRed); // false
}

如果要改成 是否有任一個紅色的水果存在,可以換用 Array.some

const fruits = [
    { name: 'apple', color: 'red' },
    { name: 'banana', color: 'yellow' },
    { name: 'grape', color: 'purple' }
];

function test() {
  // condition: 有任一個為紅色
  const isAnyRed = fruits.some(f => f.color == 'red');

  console.log(isAnyRed); // true
}


上一篇
[雜談] 幫助別人,本身就很快樂
下一篇
[題外話] 職場的那些點點滴滴 (上)
系列文
寫程式帶給我的無形快樂30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言