JavaScript中條件語句的優(yōu)化技巧總結(jié)
對多個條件使用 Array.includes
function test(fruit) { if (fruit == 'apple' || fruit == 'strawberry') { console.log('red'); } }
上面的例子看起來不錯。然而,如果還有更多紅顏色的水果需要判斷呢,比如櫻桃和小紅莓,我們要用更多的 ||來擴展這個表述嗎?
我們可以用 Array.includes 重寫上面的條件!
function test(fruit) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (redFruits.includes(fruit)) { console.log('red'); } }
我們將條件提取到一個數(shù)組中。這樣做之后,代碼看起來更整潔。
更少的嵌套,盡早返回
擴展前面的示例,以包含另外兩個條件:
如果沒有提供水果(名稱),拋出錯誤。
如果(紅色水果)數(shù)量超過 10 個,接受并打印。
看看上面的代碼,我們有:
1 組過濾無效條件的 if/else 語句
3層的 if 嵌套語句(條件 1、2 和 3)
遵循的一般規(guī)則是,當(dāng)發(fā)現(xiàn)無效條件時,提前返回。
/_ return early when invalid conditions found _/ function test(fruit, quantity) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; // condition 1: throw error early if (!fruit) throw new Error('No fruit!'); // condition 2: must be red if (redFruits.includes(fruit)) { console.log('red'); // condition 3: must be big quantity if (quantity > 10) { console.log('big quantity'); } } }
這樣,我們就少了一層嵌套。這種編碼風(fēng)格很好,尤其是當(dāng)你有很長的 if 語句時(想象一下,你需要滾動到最底部才能知道還有一個 else 語句,這并不好)。
通過反轉(zhuǎn)條件和提早返回,我們可以進一步減少嵌套。看看下面的條件 2,我們是怎么做的:
/_ return early when invalid conditions found _/ function test(fruit, quantity) { const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']; if (!fruit) throw new Error('No fruit!'); // condition 1: throw error early if (!redFruits.includes(fruit)) return; // condition 2: stop when fruit is not red console.log('red'); // condition 3: must be big quantity if (quantity > 10) { console.log('big quantity'); } }
通過反轉(zhuǎn)條件 2 的條件,我們的代碼現(xiàn)在沒有嵌套語句。當(dāng)我們有很長的邏輯要處理時,這種技術(shù)是有用的,當(dāng)一個條件沒有滿足時,我們想要停止進一步的處理。
然而,這并不是嚴格的規(guī)則。問問自己,這個版本(沒有嵌套)是否比前一個版本(嵌套的條件 2)更好、更易讀?
對于我來說,我將把它保留為以前的版本(條件 2 和嵌套)。這是因為:
代碼簡短而直接,如果嵌套,代碼就更清晰了,反轉(zhuǎn)條件可能會導(dǎo)致更多的思考過程(增加認知負擔(dān))!
因此,總是以更少的嵌套及盡早返回為目標(biāo),但不要過度。
使用默認的函數(shù)參數(shù)和解構(gòu)
在使用 JavaScript 時總是需要檢查 null 或 undefined 值并分配默認值:
function test(fruit, quantity) { if (!fruit) return; const q = quantity || 1; } //test results test('banana'); test('apple', 2);
事實上,可以通過指定默認的函數(shù)參數(shù)來消除變量 q。
function test(fruit, quantity = 1) { if (!fruit) return; } //test results test('banana'); test('apple', 2);
請注意,每個參數(shù)都可以有自己的默認函數(shù)參數(shù)。例如,我們也可以為 fruit 賦值:function test(fruit = 'unknown', quantity = 1)。
如果我們的 fruit 是一個對象:
function test(fruit) { if (fruit && fruit.name) { console.log (fruit.name); } else { console.log('unknown'); } } //test results test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple
如果 fruit.name 是可用的,我們將打印該水果名稱,否則我們將打印 unknown。我們可以避免使用與默認函數(shù)參數(shù)和解構(gòu)對條件 fruit && fruit.name進行檢查。
function test({name} = {}) { console.log (name || 'unknown'); } //test results test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple
因為我們只需要水果中的屬性 name,所以我們可以使用 {name} 來解構(gòu),然后我們可以在代碼中使用 name 作為變量,而不是 fruit.name。
我們還將空對象 {} 指定為默認值。如果我們不這樣做,當(dāng)執(zhí)行 test(undefined),不能解構(gòu) undefined 或 null 的屬性名時,您將會得到錯誤。因為在 undefined中沒有 name 屬性。
選擇 Map 或?qū)ο笞置媪?,而不?Switch 語句
我們想要基于顏色打印水果名稱:
function test(color) { // use switch case to find fruits in color switch (color) { case 'red': return ['apple', 'strawberry']; case 'yellow': return ['banana', 'pineapple']; case 'purple': return ['grape', 'plum']; default: return []; } } //test results test(null); // [] test('yellow'); // ['banana', 'pineapple']
上面的代碼似乎沒有什么問題,但發(fā)現(xiàn)它相當(dāng)冗長。同樣的結(jié)果可以通過對象字面量和更簡潔的語法來實現(xiàn):
const fruitColor = { red: ['apple', 'strawberry'], yellow: ['banana', 'pineapple'], purple: ['grape', 'plum'] }; function test(color) { return fruitColor[color] || []; }
或者,可以使用 Map 來實現(xiàn)相同的結(jié)果:
const fruitColor = new Map() .set('red', ['apple', 'strawberry']) .set('yellow', ['banana', 'pineapple']) .set('purple', ['grape', 'plum']); function test(color) { return fruitColor.get(color) || []; }
Map 是 ES2015 以后可用的對象類型,允許您存儲鍵值對。
對于上面的示例,我們實際上可以重構(gòu)代碼,以使用 Array.filter 獲得相同的結(jié)果。
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 test(color) { // use Array filter to find fruits in color return fruits.filter(f => f.color == color); }
總有不止一種方法可以達到同樣的效果。展示了 4 個相同效果的例子。
所有或部分使用 Array.every & Array.some 的條件
使用新的Javascript 數(shù)組函數(shù)來減少代碼行??纯聪旅娴拇a,我們想檢查所有的水果是否都是紅色的:
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { let isAllRed = true; // condition: all fruits must be red for (let f of fruits) { if (!isAllRed) break; isAllRed = (f.color == 'red'); } console.log(isAllRed); // false }
代碼太長了!我們可以用 Array.every 來減少行數(shù):
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { // condition: short way, all fruits must be red const isAllRed = fruits.every(f => f.color == 'red'); console.log(isAllRed); // false }
現(xiàn)在干凈多了,對吧?類似地,如果我們想用一行代碼來判斷任何一個水果是否為紅色,我們可以使用 Array.some。
const fruits = [ { name: 'apple', color: 'red' }, { name: 'banana', color: 'yellow' }, { name: 'grape', color: 'purple' } ]; function test() { // condition: if any fruit is red const isAnyRed = fruits.some(f => f.color == 'red'); console.log(isAnyRed); // true }
到此這篇關(guān)于JavaScript中條件語句的優(yōu)化技巧的文章就介紹到這了,更多相關(guān)JS條件語句優(yōu)化技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript下拉列表中顯示樹形菜單的實現(xiàn)方法
這篇文章主要介紹了javascript下拉列表中顯示樹形菜單的實現(xiàn)方法,需要的朋友可以參考下2015-11-11JavaScript iframe數(shù)據(jù)共享接口實現(xiàn)方法
在iframe與父窗口或者與子窗口傳遞數(shù)據(jù)是一個麻煩的事情,如果我們能夠?qū)懸粋€一勞永逸的接口那就再方便不過了,下面就來簡答介紹一下如何實現(xiàn)此功能,對js iframe相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧2016-01-01如何在父窗口中得知window.open()出的子窗口關(guān)閉事件
在父窗口中得知window.open()出的子窗口關(guān)閉事件的方法有很多,在本文將為大家詳細介紹下,感興趣的朋友可以參考下2013-10-10Openlayers實現(xiàn)根據(jù)半徑繪制圓形
這篇文章主要介紹了利用Openlayers實現(xiàn)繪制三個圓形,繪制完成之后,三個圓心連接起來,然后標(biāo)記出每兩個圓心之間的距離,感興趣的可以了解一下2022-08-08