如何降低程式碼複雜度 ?

栏目: IOS · 发布时间: 6年前

内容简介:ECMAScript 5ECMAScript 2015

if elseswitch case 是最基本的邏輯判斷方式,但卻也是 複雜度 的元兇,實務上善用 ECMAScript 的語言特性與 Higher Order Function,可以降低複雜度,讓程式碼可讀性更高,也更容易維護。

Version

ECMAScript 5

ECMAScript 2015

&& 與 ||

If Else

const func = product => {
  if (product === 'iPhone')
    return product;
  else
    return false;
};

console.log(func());
console.log(func('iPhone'));

若為 true 則直接回傳,否則回傳 false

如何降低程式碼複雜度 ?

&& Logic Operator

const func = product => product === 'iPhone' && product;

console.log(func());
console.log(func('iPhone'));

可使用 && ,若為 false 直接回傳 false ,若為 true 才會繼續執行 && 右側部分。

如何降低程式碼複雜度 ?

If Else

const func = product => {
  if (product === 'iPhone')
    return true;
  else
    return product;
};

console.log(func());
console.log(func('iPad'));
console.log(func('iPhone'));

若需求反過來,只有 false 直接回傳,否則回傳 true

如何降低程式碼複雜度 ?

const func = product => product === 'iPhone' || product;

console.log(func());
console.log(func('iPad'));
console.log(func('iPhone'));

可使用 || ,若為 true 直接回傳 true ,若為 false 才會繼續執行 || 右側部分。

如何降低程式碼複雜度 ?

Array.includes()

If

const func = product => {
  if (product === 'iPhone' || product === 'iPad' || product === 'Apple Watch' || product === 'Macbook') {
    return true;
  }
};

console.log(func('Apple Watch'));

常見的需求, || 若其中一個條件成立就回傳值。

如何降低程式碼複雜度 ?

Includes()

const apples = [
  'iPhone',
  'iPad',
  'Apple Watch',
  'Macbook',
];

const func = product => apples.includes(product);

console.log(func('Apple Watch'));

Array.prototype.includes() 的原意是判斷 item 是否在 array 中,若有則回傳 true ,否則傳回 false

利用 includes() 這個特性,可將所有要判斷的項目改寫在 array 中,改用 includes() 判斷,不只清爽,可讀性也很高。

如何降低程式碼複雜度 ?

Guard Clause

Nested If

const apples = [
  'iPhone',
  'iPad',
  'Apple Watch',
  'Macbook',
];

const func = (product, quantity) => {
  if (product) {
    if (apples.includes(product)) {
      console.log(`${product} is Apple product`);

      if (quantity > 10) {
        console.log('big quantity');
      }
    }
  } else {
    throw new Error('No Apple product');
  }
};

func();
func('Macbook');
func('iPad', 20);

若都使用 正向判斷 ,可能會造成 nested if else 而難以維護。

如何降低程式碼複雜度 ?

Guard Clause

const apples = [
  'iPhone',
  'iPad',
  'Apple Watch',
  'Macbook',
];

const func = (product, quantity) => {
  if (!product) throw new Error('No Apple product');

  if (!apples.includes(product)) return;
  console.log(`${product} is Apple product`);

  if (quantity > 10) console.log('big quantity');
};

func();
func('Macbook');
func('iPad', 20);

可使用 Guard Clause 將反向邏輯提早 return ,讓所有 if 判斷都扁平化只有一層,這也是為什麼有些 Lint 會警告你不能寫 else ,因為使用 Guard Clause 之後,就不會再出現 else 了。

如何降低程式碼複雜度 ?

Array.every() / Array.some()

For of

const apples = [
  { name: 'iPhone', color: 'white' },
  { name: 'iPad', color: 'black' },
  { name: 'Macbook', color: 'silver' }
];

const func = color => {
  let isSame = true;

  for (let product of apples) {
    if (!isSame) break;
    isSame = product.color === color;
  }

  return isSame;
};

console.log(func('white'));

若要 全部條件 都成立,實務上我們也會將資料與條件全部先放在 array 中。

最直覺方式就是透過 for loop 判斷。

如何降低程式碼複雜度 ?

Array.every()

const apples = [
  { name: 'iPhone', color: 'white' },
  { name: 'iPad', color: 'black' },
  { name: 'Macbook', color: 'silver' }
];

const func = color => apples.every(x => x.color === color);

console.log(func('white'));

若要 全部條件 都成立,可使用 Array.prototype.every() ,則所有條件都為 true 才會回傳 true

如何降低程式碼複雜度 ?

Array.some()

const apples = [
  { name: 'iPhone', color: 'white' },
  { name: 'iPad', color: 'black' },
  { name: 'Macbook', color: 'silver' }
];

const func = color => apples.some(x => x.color === color);

console.log(func('white'));

若只要 有一個條件 成立即可,可使用 Array.prototype.some()

如何降低程式碼複雜度 ?

Default Parameter

|| Logic Operator

const func = (product, quantity) => {
  if (!product) return;

  quantity = quantity || 1;

  return `We have ${quantity} ${product}!`;
};

console.log(func());
console.log(func('iPad'));
console.log(func('iPhone', 2));

ES5 function 並沒有提供 Default Parameter,因此會透過判斷 parameter 是否為 undefined|| 的小技巧設定預設值。

但由於 0''false 也視為 Falsy Value,若你的需求是能接受 0''false ,就不能使用這種技巧

如何降低程式碼複雜度 ?

Default Parameter

const func = (product, quantity = 1) => {
  if (!product) return;

  return `We have ${quantity} ${product}!`;
};

console.log(func());
console.log(func('iPad'));
console.log(func('iPhone', 2));

ECMAScript 2015 提供了 Default Parameter 之後,語意更加清楚,也不用判斷 undefined 了。

如何降低程式碼複雜度 ?

Object Destructing

If Else

const func = product => {
  if (product && product.name)  {
    return product.name;
  } else {
    return 'unknown';
  }
};

console.log(func());
console.log(func({}));
console.log(func({ name: 'iPhone', color: 'white' }));

若 parameter 為 object,在 ES5 為避免 parameter 為 undefinednull ,又避免根本無 property,必須小心翼翼的判斷 object 與 property。

如何降低程式碼複雜度 ?

Object Destructing

const func = ({ name } = {}) => name || 'unknown';

console.log(func());
console.log(func({}));
console.log(func({ name: 'iPhone', color: 'white' }));

透過 ECMAScript 2015 的 Default Parameter 與 Object Destructing,可一次解決判斷 object 與 property 問題。

  • 當 parameter 為 undefined 時,會使用預設值 {}
  • 當 object 沒有 property 時, Object Destructing 拆解後為 undefined ,都是 unknown
  • 否則會正常取得 property 值

如何降低程式碼複雜度 ?

Object Literal / Map / Array

Switch Case

const func = color => {
  switch (color) {
    case 'white':
      return ['iPhone', 'iPad'];
    case 'silver':
      return ['Macbook', 'Apple Watch'];
    case 'black':
      return ['Apple TV', 'Mac Pro'];
    default:
      return [];
  }
};

console.log(func());
console.log(func('white'));

switch case 在實務上也難以避免。

如何降低程式碼複雜度 ?

Object Literal

const apples = {
  white: ['iPhone', 'iPad'],
  silver: ['Macbook', 'Apple Watch'],
  black: ['Apple TV', 'Mac Pro'],
};

const func = color => apples[color] || [];

console.log(func());
console.log(func('white'));

由於 object 本身就是 key / value,因此可以把 object 當 Dictionary 使用取代 switch case

Default 值就使用 || 表示。

如何降低程式碼複雜度 ?

Map

const apples = new Map()
  .set('white', ['iPhone', 'iPad'])
  .set('silver', ['Macbook', 'Apple Watch'])
  .set('black', ['Apple TV', 'Mac Pro']);

const func = color => apples.get(color) || [];

console.log(func());
console.log(func('white'));

ECMAScript 2015 提供了新的 Map ,想法類似 object。

如何降低程式碼複雜度 ?

Array

const apples = [
  {name: 'iPhone', color: 'white'},
  {name: 'iPad', color: 'white'},
  {name: 'Macbook', color: 'silver'},
  {name: 'Apple Watch', color: 'silver'},
  {name: 'Apple TV', color: 'black'},
  {name: 'Mac Pro', color: 'black'},
];

const func = color =>
  apples
    .filter(x => x.color === color)
    .map(x => x.name);

console.log(func());
console.log(func('white'));

也可以把所有條件都放進 array,改用 Array.prototype 下豐富的 method。

如何降低程式碼複雜度 ?

Conclusion

  • 並不是所有的判斷都只能用 if elseswitch case ,透過一些 ECMAScript 的語言特性與 Higher Order Function,可以有效降低程式碼複雜度

Reference

Jecelyn Yeen , 5 Tips to Write Better Conditionals in JavaScript


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

硅谷之火

硅谷之火

保罗·弗赖伯格、迈克尔·斯韦因 / 张华伟 编译 / 中国华侨出版社 / 2014-11-1 / CNY 39.80

《硅谷之火:人与计算机的未来》以生动的故事,介绍了计算机爱好者以怎样的创新精神和不懈的努力,将计算机技术的力量包装在一个小巧玲珑的机壳里,实现了个人拥有计算机的梦想。同时以独特的视角讲述了苹果、微软、太阳微系统、网景、莲花以及甲骨文等公司的创业者们在实现个人计算机梦想的过程中创业的艰辛、守业的艰难、失败的痛苦,在激烈竞争的环境中奋斗的精神以及在技术上不断前进的历程。一起来看看 《硅谷之火》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换