也許能夠不用 If… Else

以前在寫一個 React 項目時,我發現我用了太多的 if else,因而在重構代碼的時候,我嘗試刪除了大量的 if else,最終發現代碼變簡潔了,可讀性更高了。因此若是你的代碼中也出現了大量的if else,說明你的代碼出問題了。javascript

在 code reviews 的時候,我會關注下面幾個問題:前端

  • 一個函數幹了幾件事情,是否須要分離,讓一個函數只幹一件事?
  • 檢查函數中的 if else,看是否能夠替換它。
  • 怎麼改善可讀性?好比用設計模式替換if else(我最喜歡用對象映射模式)。
  • 若是必須使用 if else,那麼刪除 else,保留 if,並返回默認值。

接下來我會舉幾個例子來展現如何替代 if elsejava

刪除 else

重構前:react

if (red) {
  return false;
} else if (blue) {
  return false;
} else {
  return true;
} 
複製代碼

重構後:後端

if (red || blue) {
    return false;
}
return true;
複製代碼

重構後的代碼能夠很直觀的看到默認返回值,更簡潔易讀。設計模式

組合函數

當你發現一個函數作了不少件事情,那麼用組合函數能夠很好的處理它。把函數分離成多個函數,而後把它們組合起來。app

舉個例子:咱們來建立一個能夠生成包含皮毛和爪子的雌性動物的函數函數

import { flow } from 'lodash';

const femaleAnimalsWithFurAndClaws = flow(
  getFemales,
  getAnimalsWithFur,
  getAnimalsWithClaws,
)(animals);
複製代碼

代碼處理成這樣,咱們能夠很輕鬆的重用裏面的函數(好比 getFemales)。編碼

對象映射模式

這是我最喜歡的設計模式之一,可以使用的場景也不少,無論是在前端仍是後端編碼中均可以用。它帶來的好處就是,讓代碼簡潔易讀。每次我用這種設計模式的時候,我都以爲個人代碼不是代碼,而是說明書(^_^)。spa

來看一個簡單的例子:

const colors = {
  red: false,
  blue: false,
  'default': true,
 };

const colorMapper = color => colors[color] || colors['default'];

const color = colorMapper(item.color);
複製代碼

它由兩個部分組成,一個儲存返回結果的對象和一個映射函數。

咱們設置了默認值,即便在調用 colorMapper 函數的時候,沒有傳入參數,或者傳入了錯誤參數,都不會報錯,並返回默認值。後期維護的時候,咱們也能夠很輕鬆的新增其餘的顏色。

固然咱們也能夠用 switch 來達到一樣的效果,就我我的而言並不喜歡這種語法,仍是對象映射的方式更簡潔優美(^_^)。

對象映射模式 + React

用 React 寫項目,纔是對象映射模式大放異彩的時候。當咱們渲染不少不一樣的組件時,咱們須要在代碼中寫大量的條件判斷。若是用對象映射模式,問題就變得簡單了。看下面的例子:

首先數據看起來是這樣的,每一個對象都有一個 typecontent 鍵。

const items = [{
 type: ‘hero’,
 content: : {…},
}, {
 type: 'text',
 content: : {…},
}, {
 type: 'image_and_text',
 content: : {…},
}, {
 type: 'text',
 content: : {…},
}, {
 type: 'call_to_action',
 content: : {…},
}];
複製代碼

而後寫一個映射函數,每一個鍵表示一個 React 組件,每一個組件都有 prop,就上面數據中的 content

const components = {
 hero: HeroComponent,
 text: TextComponent,
 image_and_text: ImageAndTextComponent,
 call_to_action: CallToActionComponent,
 'default': null,
};

const componentMapper = type => 
components[type] || components['default'];
複製代碼

接下來就能夠在項目中用了:

import react from ‘react’;

const RenderItems = props => {
 
 const componentList = props.items((item, index) => {
   const Component = componentMapper(item.type);
   return <Component content={item.content} /> }; return ( <div> {componentList} </div> ) }; 複製代碼

感謝閱讀!

本文翻譯自Fredrik JensenIf… Else, or not!

相關文章
相關標籤/搜索