溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript語法和React JSX語法的邏輯判斷優(yōu)化技巧有哪些

發(fā)布時(shí)間:2022-03-18 10:33:19 來源:億速云 閱讀:142 作者:小新 欄目:開發(fā)技術(shù)

小編給大家分享一下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 個(gè)
            if (quantity > 10) {
                console.log('數(shù)量大于 10 個(gè)');
            }
        }
    } else {
        throw new Error('沒有水果啦!');
    }
}

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

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

function supply(fruit, quantity) {
    const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];
    if(!fruit) throw new Error('沒有水果啦'); // 條件 1: 當(dāng) fruit 無效時(shí),提前處理錯(cuò)誤
    if(!redFruits.includes(fruit)) return; // 條件 2: 當(dāng)不是紅色水果時(shí),提前 return

    
    console.log('紅色水果');

    
    // 條件 3: 水果數(shù)量大于 10 個(gè)
    if (quantity > 10) {
        console.log('數(shù)量大于 10 個(gè)');
    }
}

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

當(dāng)需要枚舉值處理不同的業(yè)務(wù)分支邏輯時(shí), 第一反應(yīng)是寫下 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 [];
  }
}

在上面的實(shí)現(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 } 結(jié)構(gòu),我們可以在 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ù)結(jié)構(gòu),真正的 (key, value) 鍵值對結(jié)構(gòu) ;

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)化之后,代碼更簡潔、更容易擴(kuò)展。

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

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);
}

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

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

多條件判斷

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

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

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

試試 Array.includes ~

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

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

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
}

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

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

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ù)組中是否有某一項(xiàng)滿足條件

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

如果想知道是否有紅色水果,可以直接使用 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.reduce、Array.splice 等,在實(shí)際場景中可以根據(jù)需要選擇使用。

函數(shù)默認(rèn)值

使用默認(rèn)參數(shù)

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

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

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

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

JavaScript語法和React JSX語法的邏輯判斷優(yōu)化技巧有哪些

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

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

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

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

使用解構(gòu)與默認(rèn)參數(shù)

當(dāng)函數(shù)參數(shù)是對象時(shí),我們可以使用解構(gòu)結(jié)合默認(rèn)參數(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)
}

復(fù)雜數(shù)據(jù)解構(gòu)

當(dāng)處理比較簡的對象時(shí),解構(gòu)與默認(rèn)參數(shù)的配合是非常好的,但在一些復(fù)雜的場景中,我們面臨的可能是更復(fù)雜的結(jié)構(gòu)。

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

這個(gè)時(shí)候如果再通過解構(gòu)去獲取對象里的值。

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

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

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

import lodashGet from 'lodash/get';


const { name,price} = lodashGet(oneComplexObj,'firstLevel.secondLevel[0]',{});

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

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

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

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ī)則時(shí)調(diào)用相應(yīng)的行為。

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});

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

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

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

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

JSX-Control-Statements

JSX-Control-Statements 是一個(gè) Babel 插件,它擴(kuò)展了 JSX 的能力,支持以標(biāo)簽的形式處理?xiàng)l件判斷、循環(huán)。

If 標(biāo)簽

<If> 標(biāo)簽內(nèi)容只有在 conditiontrue 時(shí)才會(huì)渲染,等價(jià)于最簡單的三元表達(dá)式。

Before:

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

After:

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

注意:<Else /> 已被廢棄,復(fù)雜的條件判斷可以使用 <Choose> 標(biāo)簽。

Choose 標(biāo)簽

<Choose> 標(biāo)簽下包括至少一個(gè) <When> 標(biāo)簽、可選的 <Otherwise> 標(biāo)簽。

<When> 標(biāo)簽內(nèi)容只有在 conditiontrue 時(shí)才會(huì)渲染,相當(dāng)于一個(gè) if 條件判斷分支。

<Otherwise> 標(biāo)簽則相當(dāng)于最后的 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 標(biāo)簽

<For> 標(biāo)簽需要聲明 of、each 屬性。

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

each 代表迭代器訪問時(shí)的當(dāng)前指向元素。

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> 標(biāo)簽不能作為根元素。

With 標(biāo)簽

<With> 標(biāo)簽提供變量傳參的功能。

Before:

renderFoo = (foo) => {
    return <span>{ foo }</span>;
}


// JSX 中表達(dá)式調(diào)用
{
    this.renderFoo(47)
}

After:

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

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

看完了這篇文章,相信你對“JavaScript語法和React JSX語法的邏輯判斷優(yōu)化技巧有哪些”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI