国产chinesehdxxxx野外,国产av无码专区亚洲av琪琪,播放男人添女人下边视频,成人国产精品一区二区免费看,chinese丰满人妻videos

    <thead id="qwxxe"></thead>
    <bdo id="qwxxe"></bdo>
    <bdo id="qwxxe"></bdo>
    <span id="qwxxe"></span>
    <rt id="qwxxe"><optgroup id="qwxxe"></optgroup></rt>
    App下載

    代碼優(yōu)化技巧 : 邏輯判斷

    猿友 2020-08-10 18:00:05 瀏覽數(shù) (3695)
    反饋

    想成為一名合格的程序員,那么代碼優(yōu)化是相當重要的一部分,一份高質量的代碼,可以讓人一目了然,既方便自己,也方便他人。

    if else、switch case 是日常開發(fā)中最常見的條件判斷語句,這種看似簡單的語句,當遇到復雜的業(yè)務場景時,如果處理不善,就會出現(xiàn)大量的邏輯嵌套,可讀性差并且難以擴展。

    編寫高質量可維護的代碼,我們先從最小處入手,一起來看看在前端開發(fā)過程中,可以從哪些方面來優(yōu)化邏輯判斷?

    下面我們會分別從 JavaScript 語法和 React JSX 語法兩個方面來分享一些優(yōu)化的技巧。

    JavaScript 語法篇

    嵌套層級優(yōu)化

    function supply(fruit, quantity) {
        const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
        // 條件 1: 水果存在
        if(fruit) {
            // 條件 2: 屬于紅色水果
            if(redFruits.includes(fruit)) {
                console.log('紅色水果');
                // 條件 3: 水果數(shù)量大于 10 個
                if (quantity > 10) {
                    console.log('數(shù)量大于 10 個');
                }
            }
        } else {
            throw new Error('沒有水果啦!');
        }
    }

    分析上面的條件判斷,存在三層 if 條件嵌套。

    如果提前 return 掉無效條件,將 if else的多重嵌套層次減少到一層,更容易理解和維護。

    function supply(fruit, quantity) {
        const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
        if(!fruit) throw new Error('沒有水果啦'); // 條件 1: 當 fruit 無效時,提前處理錯誤
        if(!redFruits.includes(fruit)) return; // 條件 2: 當不是紅色水果時,提前 return
    
        
        console.log('紅色水果');
    
        
        // 條件 3: 水果數(shù)量大于 10 個
        if (quantity > 10) {
            console.log('數(shù)量大于 10 個');
        }
    }

    多條件分支的優(yōu)化處理

    當需要枚舉值處理不同的業(yè)務分支邏輯時, 第一反應是寫下 if else ?我們來看一下:

    function pick(color) {
      // 根據(jù)顏色選擇水果
      if(color === 'red') {
          return ['apple', 'strawberry']; 
      } else if (color === 'yellow') {
          return ['banana', 'pineapple'];
      } else if (color === 'purple') {
          return ['grape', 'plum'];
      } else {
          return [];
      }
    }

    在上面的實現(xiàn)中:

    • if else 分支太多
    • if else 更適合于條件區(qū)間判斷,而 switch case 更適合于具體枚舉值的分支判斷

    使用 switch case 優(yōu)化上面的代碼后:

    function pick(color) {
      // 根據(jù)顏色選擇水果
      switch (color) {
        case 'red':
          return ['apple', 'strawberry'];
        case 'yellow':
          return ['banana', 'pineapple'];
        case 'purple':
          return ['grape', 'plum'];
        default:
          return [];
      }
    }

    switch case 優(yōu)化之后的代碼看上去格式整齊,思路很清晰,但還是很冗長。繼續(xù)優(yōu)化:

    • 借助 Object{ key: value } 結構,我們可以在 Object 中枚舉所有的情況,然后將 key 作為索引,直接通過 Object.key 或者 Object[key] 來獲取內(nèi)容

    const fruitColor = {                                                                        
        red: ['apple', 'strawberry'],
        yellow: ['banana', 'pineapple'],
        purple: ['grape', 'plum'],
    }
    function pick(color) {
        return fruitColor[color] || [];
    }

    • 使用 Map 數(shù)據(jù)結構,真正的 (key, value) 鍵值對結構 ;

    const fruitColor = new Map()
    .set('red', ['apple', 'strawberry'])
    .set('yellow', ['banana', 'pineapple'])
    .set('purple', ['grape', 'plum']);
    
    
    function pick(color) {
      return fruitColor.get(color) || [];
    }

    優(yōu)化之后,代碼更簡潔、更容易擴展。

    為了更好的可讀性,還可以通過更加語義化的方式定義對象,然后使用 Array.filter 達到同樣的效果。

    const fruits = [
        { name: 'apple', color: 'red' }, 
        { name: 'strawberry', color: 'red' }, 
        { name: 'banana', color: 'yellow' }, 
        { name: 'pineapple', color: 'yellow' }, 
        { name: 'grape', color: 'purple' }, 
        { name: 'plum', color: 'purple' }
    ];
    
    
    function pick(color) {
      return fruits.filter(f => f.color == color);
    }

    (推薦教程:JavaScript教程

    使用數(shù)組新特性簡化邏輯判斷

    巧妙的利用 ES6 中提供的數(shù)組新特性,也可以讓我們更輕松的處理邏輯判斷。

    多條件判斷

    編碼時遇到多個判斷條件時,本能的寫下下面的代碼(其實也是最能表達業(yè)務邏輯的面向過程編碼)。

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

    但是當 type 未來到 10 種甚至更多時, 我們只能繼續(xù)添加 || 來維護代碼么 ?

    試試 Array.includes ~

    // 將判斷條件抽取成一個數(shù)組
    const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
    function judge(type) {
        if (redFruits.includes(fruit)) {
            console.log('red');
         }
    }

    判斷數(shù)組中是否所有項都滿足某條件

    const fruits = [
        { name: 'apple', color: 'red' },
        { name: 'banana', color: 'yellow' },
        { name: 'grape', color: 'purple' }
      ];
    
    
    function match() {
      let isAllRed = true;
    
    
      // 判斷條件:所有的水果都必須是紅色
      for (let f of fruits) {
        if (!isAllRed) break;
        isAllRed = (f.color === 'red');
      }
    
    
      console.log(isAllRed); // false
    }

    上面的實現(xiàn)中,主要是為了處理數(shù)組中的所有項都符合條件。

    使用 Array.every 可以很容的實現(xiàn)這個邏輯:

    const fruits = [
        { name: 'apple', color: 'red' },
        { name: 'banana', color: 'yellow' },
        { name: 'grape', color: 'purple' }
      ];
    
    
    function match() {
      // 條件:所有水果都必須是紅色
      const isAllRed = fruits.every(f => f.color == 'red');
    
    
      console.log(isAllRed); // false
    }

    判斷數(shù)組中是否有某一項滿足條件

    Array.some ,它主要處理的場景是判斷數(shù)組中是否有一項滿足條件。

    如果想知道是否有紅色水果,可以直接使用 Array.some 方法:

    const fruits = [
        { name: 'apple', color: 'red' },
        { name: 'banana', color: 'yellow' },
        { name: 'grape', color: 'purple' }
      ];
    
    
    // 條件:是否有紅色水果 
    const isAnyRed = fruits.some(f => f.color == 'red');

    還有許多其他數(shù)組新特性,比如 Array.findArray.slice、Array.findIndex、Array.reduceArray.splice 等,在實際場景中可以根據(jù)需要選擇使用。

    函數(shù)默認值

    使用默認參數(shù)

    const buyFruit = (fruit,amount) => {
         if(!fruit){
            return
      }
      amount = amount || 1;
      console.log(amount)
    }

    我們經(jīng)常需要處理函數(shù)內(nèi)部的一些參數(shù)默認值,上面的代碼大家都不陌生,使用函數(shù)的默認參數(shù),可以很好的幫助處理這種場景。

    const buyFruit = (fruit,amount = 1) => {
         if(!fruit){
            return
      }
      console.log(amount,'amount')
    }

    我們可以通過 Babel 的轉譯來看一下默認參數(shù)是如何實現(xiàn)的。

    默認參數(shù)

    從上面的轉譯結果可以發(fā)現(xiàn),只有參數(shù)為 undefined 時才會使用默認參數(shù)。

    測試的執(zhí)行結果如下:

    buyFruit('apple','');  // amount
    buyFruit('apple',null);  //null amount
    buyFruit('apple');  //1 amount

    所以使用默認參數(shù)的情況下,我們需要注意的是默認參數(shù) amount=1 并不等同于 amount || 1

    使用解構與默認參數(shù)

    當函數(shù)參數(shù)是對象時,我們可以使用解構結合默認參數(shù)來簡化邏輯。

    Before:

    const buyFruit = (fruit,amount) => {
        fruit = fruit || {};
        if(!fruit.name || !fruit.price){
            return;
        }
        ...
      amount = amount || 1;
      console.log(amount)
    }

    After:

    const buyFruit = ({ name,price }={},amount) => {
      if(!name || !prices){
          return;
      }
      console.log(amount)
    }

    復雜數(shù)據(jù)解構

    當處理比較簡的對象時,解構與默認參數(shù)的配合是非常好的,但在一些復雜的場景中,我們面臨的可能是更復雜的結構。

    const oneComplexObj = {
        firstLevel:{
            secondLevel:[{
                name:"",
                price:""
            }]
        }
    }

    這個時候如果再通過解構去獲取對象里的值。

    const {
        firstLevel:{
            secondLevel:[{name,price]=[]
        }={}
    } = oneComplexObj;        

    可讀性就會比較差,而且需要考慮多層解構的默認值以及數(shù)據(jù)異常情況。

    這種情況下,如果項目中使用 lodash 庫,可以使用其中的 lodash/get 方法。

    import lodashGet from 'lodash/get';
    
    
    const { name,price} = lodashGet(oneComplexObj,'firstLevel.secondLevel[0]',{});

    策略模式優(yōu)化分支邏輯處理

    策略模式:定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。

    使用場景:策略模式屬于對象行為模式,當遇到具有相同行為接口、行為內(nèi)部不同邏輯實現(xiàn)的實例對象時,可以采用策略模式;或者是一組對象可以根據(jù)需要動態(tài)的選擇幾種行為中的某一種時,也可以采用策略模式;這里以第二種情況作為示例:

    Before:

    const TYPE = {
        JUICE:'juice',
        SALAD:'salad',
        JAM:'jam'
    }
    function enjoy({type = TYPE.JUICE,fruits}){
      if(!fruits || !fruits.length) {
            console.log('請先采購水果!');
               return;
        }
      if(type === TYPE.JUICE) {
        console.log('榨果汁中...');
          return '果汁';
      }
      if(type === TYPE.SALAD) {
          console.log('做沙拉中...');
          return '拉沙';
      }
      if(type === TYPE.JAM) {
        console.log('做果醬中...');
          return '果醬';
      }
      return;
    }
    
    
    enjoy({type:'juice',fruits});

    使用思路:定義策略對象封裝不同行為、提供策略選擇接口,在不同的規(guī)則時調用相應的行為。

    After:

    const TYPE = {
        JUICE:'juice',
        SALAD:'salad',
        JAM:'jam'
    }
    
    
    const strategies = {
        [TYPE.JUICE]: function(fruits){
            console.log('榨果汁中...');
            return '果汁';
        },
        [TYPE.SALAD]:function(fruits){
            console.log('做沙拉中...');
            return '沙拉';
        },
        [TYPE.JAM]:function(fruits){
            console.log('做果醬中...');
            return '果醬';
        },
    }
    
    
    function enjoy({type = TYPE.JUICE,fruits}) {
        if(!type) {
            console.log('請直接享用!');
               return;
        }
        if(!fruits || !fruits.length) {
            console.log('請先采購水果!');
               return;
        }
        return strategies[type](fruits);
    }
    
    
    enjoy({type:'juice',fruits});

    (推薦微課:JavaScript微課

    框架篇之 React JSX 邏輯判斷優(yōu)化

    JSX 是一個看起來很像 XMLJavaScript 語法擴展。一般在 React 中使用 JSX 來描述界面信息,ReactDOM.render()JSX 界面信息渲染到頁面上。

    JSX 中支持 JavaScript 表達式,日常很常見的循環(huán)輸出子組件、三元表達式判斷、再復雜一些直接抽象出一個函數(shù)。

    JSX 中寫這么多 JavaScript 表達式,整體代碼看起來會有點兒雜亂。試著優(yōu)化一下!

    JSX-Control-Statements

    JSX-Control-Statements 是一個 Babel 插件,它擴展了 JSX 的能力,支持以標簽的形式處理條件判斷、循環(huán)。

    If 標簽

    <If> 標簽內(nèi)容只有在 conditiontrue 時才會渲染,等價于最簡單的三元表達式。

    Before:

    { condition() ? 'Hello World!' : null }

    After:

    <If condition={ condition() }>Hello World!</If>

    注意:<Else /> 已被廢棄,復雜的條件判斷可以使用 <Choose> 標簽。

    Choose 標簽

    <Choose> 標簽下包括至少一個 <When> 標簽、可選的 <Otherwise> 標簽。

    <When> 標簽內(nèi)容只有在 conditiontrue 時才會渲染,相當于一個 if 條件判斷分支。

    <Otherwise> 標簽則相當于最后的 else分支。

    Before:

    { test1 ? <span>IfBlock1</span> : test2 ? <span>IfBlock2</span> : <span>ElseBlock</span> }

    After:

    <Choose>
      <When condition={ test1 }>
        <span>IfBlock1</span>
      </When>
      <When condition={ test2 }>
        <span>IfBlock2</span>
      </When>
      <Otherwise>
        <span>ElseBlock</span>
      </Otherwise>
    </Choose>

    For 標簽

    <For> 標簽需要聲明 of、each 屬性。

    of 接收的是可以使用迭代器訪問的對象。

    each 代表迭代器訪問時的當前指向元素。

    Before:

    {
      (this.props.items || []).map(item => {
          return <span key={ item.id }>{ item.title }</span>
      })
    }

    After:

    <For each="item" of={ this.props.items }>
       <span key={ item.id }>{ item.title }</span>
    </For>

    注意:<For> 標簽不能作為根元素。

    With 標簽

    <With> 標簽提供變量傳參的功能。

    Before:

    renderFoo = (foo) => {
        return <span>{ foo }</span>;
    }
    
    
    // JSX 中表達式調用
    {
        this.renderFoo(47)
    }

    After:

    <With foo={ 47 }>
      <span>{ foo }</span>
    </With>

    使用這幾種標簽優(yōu)化代碼,可以減少 JSX 中存在的顯式 JavaScript 表達式,使我們的代碼看上去更簡潔,但是這些標簽封裝的能力,在編譯時需要轉換為等價的 JavaScript 表達式。

    總結

    以上就是一些常見的邏輯判斷優(yōu)化技巧總結。當然,編寫高質量可維護的代碼,除了邏輯判斷優(yōu)化,還需要有清晰的注釋、含義明確的變量命名、合理的代碼結構拆分、邏輯分層解耦、以及更高層次的貼合業(yè)務的邏輯抽象等等,相信各位在這方面也有自己的一些心得。

    0 人點贊