javascript
if test 多条件_五条写好JavaScript条件语句的建议(译)
1. 多重準則時使用 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ù)組存放提取出的紅色的水果,這樣做使用代碼看起來整潔很多。
2. 少些嵌套,提前返回
讓我們增加多兩個條件繼續(xù)擴展之前的栗子: - 如果沒有水果,則拋出錯誤 - 如果水果數(shù)量大于10則打印出來
function test(fruit, quantity) {const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];// 條件 1: 水果必須有值if (fruit) {// 條件 2: 水果必須是紅色的if (redFruits.includes(fruit)) {console.log('red');// 條件 3: 水果數(shù)量足夠多if (quantity > 10) {console.log('big quantity');}}} else {throw new Error('No fruit!');} }// 測試 test(null); // error: No fruits test('apple'); // print: red test('apple', 20); // print: red, big quantity上面的實現(xiàn),不難看出:
- 1條if/else語句過濾掉無效的條件
- 3重if嵌套語句(條件1、2和3)
我個人遵循的一般規(guī)則是當發(fā)現(xiàn)無效的條件時,提前返回。
function test(fruit, quantity) {const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];// 條件 1: 盡早拋出錯誤if (!fruit) throw new Error('No fruit!');// 條件 2: 必須是紅色的if (redFruits.includes(fruit)) {console.log('red');// 條件 3: 水果數(shù)量必須符合if (quantity > 10) {console.log('big quantity');}} }通過這么改進后,就少了一層嵌套語句。這種代碼風格就顯得優(yōu)雅很多,特多是有很多層if語句的時候。(想象一下你需要滾動很長的篇幅才能看到一個else語句,這樣一點也不酷)
通過反轉條件 & 盡早返回,我們還可以更進一步減少if嵌套??纯聪旅娴臈l件2我們怎么做:
function test(fruit, quantity) {const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries'];// 條件 1: 盡早拋出錯誤if (!fruit) throw new Error('No fruit!'); // 條件 2: 當水果不是紅色的就結束if (!redFruits.includes(fruit)) return; console.log('red');// 條件 3: 必須是符合數(shù)量的if (quantity > 10) {console.log('big quantity');} }通過反轉條件2,現(xiàn)在我們的代碼少了一層嵌套語句。當我們有很長的邏輯要執(zhí)行和條件不滿足時停止執(zhí)行,這種做法是非常有用的。
然而,沒有嚴格的限制必須要這么做。這時候要問問你自己,這么做(沒有嵌套)后是否比之前的(有嵌套的)更好/代碼可讀性更高。
對于我,我更偏向于之前嵌套那個版本,因為:
- 代碼更簡短、直接
- 反轉條件也許會帶來更多的思考環(huán)節(jié)(增加認知負擔)
可以通過減少嵌套和盡早返回,但不要過度這么做。如果你對于這些話題有興趣,可以參考下面的一篇文章和StackOverflow討論:
Avoid Else, Return Early?blog.timoxley.comShould I return from a function early or use an if statement??softwareengineering.stackexchange.com3. 使用默認函數(shù)參數(shù)和解構
我猜下面的代碼你可能很熟悉,我們總是要檢查值是否為null或者undefined和賦默認值。
function test(fruit, quantity) {if (!fruit) return;const q = quantity || 1; console.log(`We have ${q} ${fruit}!`); }test('banana'); // We have 1 banana! test('apple', 2); // We have 2 apple!事實上,我們可以通過給函數(shù)參數(shù)賦賦默認值來消除變量q。
function test(fruit, quantity = 1) { if (!fruit) return;console.log(`We have ${quantity} ${fruit}!`); }test('banana'); // We have 1 banana! test('apple', 2); // We have 2 apple!是不是更容易和更直觀了?請注意,每個參數(shù)都可以有它自己的默認函數(shù)參數(shù)。例如,也可以給參數(shù)fruit賦默認值:function test(fruit = 'unknown', quantity = 1)
如果參數(shù)fruit是一個對象,我們還可以給參數(shù)設置默認值嗎?
function test(fruit) { if (fruit && fruit.name) {console.log (fruit.name);} else {console.log('unknown');} }test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple看看上面的示例中,如果希望輸出可用的或者未知的水果名稱??梢酝ㄟ^檢查默認函數(shù)參數(shù)和結構來避免條件判斷fruit && fruit.name
// 結構 - 只獲取name屬性 // 設置默認的空對象{} function test({name} = {}) {console.log (name || 'unknown'); }test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple因為我們只需要水果的屬性name,可以使用析構函數(shù)參數(shù){name},然后可以使用變量name而不需要使用 fruit.name。
我們還將空對象{}指定為默認值。如果沒這么做,當執(zhí)行到test(undefined)時會出錯,因為屬性name是未定義的。
如果你不介意使用第三方依賴庫,還有一些方法可以減少null的檢查: - 使用Lodash的get函數(shù) - 使用Facebook開源的idx庫
使用Lodash的栗子:
function test(fruit) {console.log(__.get(fruit, 'name', 'unknown'); }test(undefined); // unknown test({ }); // unknown test({ name: 'apple', color: 'red' }); // apple4. 偏于Map / Object而不是使用Switch語句
我們想根據(jù)顏色輸出水果:
function test(color) {switch (color) {case 'red':return ['apple', 'strawberry'];case 'yellow':return ['banana', 'pineapple'];case 'purple':return ['grape', 'plum'];default:return [];} }test(null); // [] test('yellow'); // ['banana', 'pineapple']上面的栗子看起來似乎沒有什么不正確的,但我發(fā)現(xiàn)它很啰嗦??梢酝ㄟ^更簡潔的對象字面量來達到同樣的效果:
const fruitColor = {red: ['apple', 'strawberry'],yellow: ['banana', 'pineapple'],purple: ['grape', 'plum']};function test(color) {return fruitColor[color] || []; }或者可以使用Map也可以實現(xiàn)同樣的需求:
const fruitColor = new Map().set('red', ['apple', 'strawberry']).set('yellow', ['banana', 'pineapple']).set('purple', ['grape', 'plum']);function test(color) {return fruitColor.get(color) || []; }我們使用禁止使用switch語句呢?建議不要這么限制自己。個人而言,是盡可能使用對象字面量,但不會設置嚴格的限制這么做,無論使用哪種都應該是你的表達更有意義。
Todd Motto有一篇文章深入討論switch語句和對象字面量。
對于上面的栗子,我們可以使用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 test(color) {return fruits.filter(f => f.color == color); }5. 使用Array.every & Array.some
最后的建議是關于利用新的數(shù)組函數(shù)去減少代碼的行數(shù)。我們需要檢驗是否所有的水果都是紅色,看下面的實現(xiàn):
const fruits = [{ name: 'apple', color: 'red' },{ name: 'banana', color: 'yellow' },{ name: 'grape', color: 'purple' }];function test() {let isAllRed = true;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() {const isAllRed = fruits.every(f => f.color == 'red');console.log(isAllRed); // false }是不是代碼簡潔了很多?同樣,如果我們想要檢驗是否有紅色的水果,可以使用Array.some來達到同樣的效果:
const fruits = [{ name: 'apple', color: 'red' },{ name: 'banana', color: 'yellow' },{ name: 'grape', color: 'purple' } ];function test() {const isAnyRed = fruits.some(f => f.color == 'red');console.log(isAnyRed); // true }總結
讓我們寫更多可讀性高的代碼,我希望這篇文章對你有所幫助。
原文
5 Tips to Write Better Conditionals in JavaScript?scotch.io總結
以上是生活随笔為你收集整理的if test 多条件_五条写好JavaScript条件语句的建议(译)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python中utf-8是什么意思_py
- 下一篇: page fault in nonpag