您好,登錄后才能下訂單哦!
小編給大家分享一下JavaScript語法和React JSX語法的邏輯判斷優(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è)'); } }
當(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); }
巧妙的利用 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'); } }
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 }
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.find
、Array.slice
、Array.findIndex
、Array.reduce
、Array.splice
等,在實(shí)際場景中可以根據(jù)需要選擇使用。
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)的。
從上面的轉(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
。
當(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) }
當(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]',{});
策略模式:定義一系列的算法,把它們一個(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});
JSX
是一個(gè)看起來很像 XML
的 JavaScript
語法擴(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
是一個(gè) Babel
插件,它擴(kuò)展了 JSX
的能力,支持以標(biāo)簽的形式處理?xiàng)l件判斷、循環(huán)。
<If>
標(biāo)簽內(nèi)容只有在 condition
為 true
時(shí)才會(huì)渲染,等價(jià)于最簡單的三元表達(dá)式。
Before:
{ condition() ? 'Hello World!' : null }
After:
<If condition={ condition() }>Hello World!</If>
注意:<Else />
已被廢棄,復(fù)雜的條件判斷可以使用 <Choose>
標(biāo)簽。
<Choose>
標(biāo)簽下包括至少一個(gè) <When>
標(biāo)簽、可選的 <Otherwise>
標(biāo)簽。
<When>
標(biāo)簽內(nèi)容只有在 condition
為 true
時(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)簽需要聲明 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)簽提供變量傳參的功能。
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è)資訊頻道,感謝各位的閱讀!
免責(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)容。