写好JS条件语句需要遵循的守则,这篇真的太可了!

***小编要跟大家分享的文章是关于Web前端写好JS条件语句需要遵循的守则。熟悉Web前端工作的小伙伴都知道在用JavaScript
工作时,我们经常和条件语句打交道,***小编就为大家准备了5条让你写出好的,干净的条件语句的建议,下面让我们一起来看一看吧~
1、多重判断时使用Array.includes
让我们看一下下面这个例子:
//condition
functiontest(fruit){
if(fruit=='apple'||fruit=='strawberry'){
console.log('red');
}
}
***眼,上面这个例子看起来没问题。如果我们有更多名字叫cherry和cranberries的红色水果呢?我们准备用更多的||来拓展条件语句吗?
我们可以用Array.includes(Array.includes)重写条件语句。
functiontest(fruit){
constredFruits=['apple','strawberry','cherry','cranberries'];
if(redFruits.includes(fruit)){
console.log('red');
}
}
我们把红色的水果(redfruits)这一判断条件提取到一个数组。这样一来,代码看起来更整洁。
2、更少的嵌套,尽早Return
让我们拓展上一个例子让它包含两个条件。
·如果没有传入参数fruit,抛出错误
·接受quantity参数,并且在quantity大于10时打印出来
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry','cranberries'];
//条件1:fruit必须有值
if(fruit){
//条件2:必须是red的
if(redFruits.includes(fruit)){
console.log('red');
//条件3:quantity大于10
if(quantity>10){
console.log('bigquantity');
}
}
}else{
thrownewError('Nofruit!');
}
}
//测试结果
test(null);//error:Nofruits
test('apple');//print:red
test('apple',20);//print:red,bigquantity
在上面的代码,我们有:
·1个if/else语句筛选出无效的语句
·3层if嵌套语句(条件1,2&3)
我个人遵循的规则一般是在发现无效条件时,尽早Return。
/_当发现无效语句时,尽早Return_/
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry','cranberries'];
//条件1:尽早抛出错误
if(!fruit)thrownewError('Nofruit!');
//条件2:必须是红色的
if(redFruits.includes(fruit)){
console.log('red');
//条件3:必须是大质量的
if(quantity>10){
console.log('bigquantity');
}
}
}
这样一来,我们少了一层嵌套语句。这种编码风格非常好,尤其是当你有很长的if语句的时候(想象你需要滚动到比较低层才知道还有else语句,这并不酷)
我们可以通过倒置判断条件&尽早return进一步减少if嵌套。看下面我们是怎么处理判断条件2的:
/_当发现无效语句时,尽早Return_/
functiontest(fruit,quantity){
constredFruits=['apple','strawberry','cherry','cranberries'];
//条件1:尽早抛出错误
if(!fruit)thrownewError('Nofruit!');
//条件2:当水果不是红色时停止继续执行
if(!redFruits.includes(fruit))return;
console.log('red');
//条件3:必须是大质量的
if(quantity>10){
console.log('bigquantity');
}
}
通过倒置判断条件2,我们的代码避免了嵌套语句。这个技巧在我们需要进行很长的逻辑判断时是非常有用的,特别是我们希望能够在条件不满足时能够停止下来进行处理。
而且这么做并不困难。问问自己,这个版本(没有嵌套)是不是比之前的(两层条件嵌套)更好,可读性更高?
但对于我,我会保留先前的版本(包含两层嵌套)。这是因为:
·代码比较短且直接,包含if嵌套的更清晰
·倒置判断条件可能加重思考的负担(增加认知载荷)
因此,应当尽力减少嵌套和尽早return,但不要过度。
3、使用默认参数和解构
我猜下面的代码你可能会熟悉,在JavaScript中我们总是需要检查null/undefined的值和指定默认值:
functiontest(fruit,quantity){
if(!fruit)return;
//如果quantity参数没有传入,设置默认值为1
constq=quantity||1;
console.log(`Wehave${q}${fruit}!`);
}
//testresults
test('banana');//Wehave1banana!
test('apple',2);//Wehave2apple!
实际上,我们可以通过声明默认函数参数来消除变量q。
functiontest(fruit,quantity=1){
//如果quantity参数没有传入,设置默认值为1
if(!fruit)return;
console.log(`Wehave${quantity}${fruit}!`);
}
//testresults
test('banana');//Wehave1banana!
test('apple',2);//Wehave2apple!
这更加直观,不是吗?注意,每个声明都有自己的默认参数.
例如,我们也能给fruit分配默认值:functiontest(fruit='unknown',quantity=1)。
如果fruit是一个object会怎么样?我们能分配一个默认参数吗?
functiontest(fruit){
//当值存在时打印fruit的值
if(fruit&&fruit.name){
console.log(fruit.name);
}else{
console.log('unknown');
}
}
//testresults
test(undefined);//unknown
test({});//unknown
test({name:'apple',color:'red'});//apple
看上面这个例子,我们想打印fruit对象中可能存在的name属性。否则我们将打印unknown。我们可以通过默认参数以及解构从而避免判断条件fruit&&fruit.name
//解构-**获取name属性
//为其赋默认值为空对象
functiontest({name}={}){
console.log(name||'unknown');
}
//testresults
test(undefined);//unknown
test({});//unknown
test({name:'apple',color:'red'});//apple
由于我们只需要name属性,我们可以用{name}解构出参数,然后我们就能使用变量name代替fruit.name。
我们也需要声明空对象{}作为默认值。如果我们不这么做,当执行test(undefined)时,你将得到一个无法对undefined或
ull解构的的错误。因为在undefined中没有name属性。
如果你不介意使用第三方库,这有一些方式减少null的检查:
·使用Lodashget函数
·使用Facebook开源的idx库(withBabeljs)
这是一个使用Lodash的例子:
functiontest(fruit){
//获取属性名,如果属性名不可用,赋默认值为unknown
console.log(__.get(fruit,'name','unknown');
}
//testresults
test(undefined);//unknown
test({});//unknown
test({name:'apple',color:'red'});//apple
你可以在jsbin运行demo代码。除此之外,如果你是函数式编程的粉丝,你可能选择使用Lodash
fp,Lodash的函数式版本(方法变更为get或者getOr)。
4、倾向于对象遍历而不是Switch语句
让我们看下面这个例子,我们想根据color打印出水果:
functiontest(color){
//使用条件语句来寻找对应颜色的水果
switch(color){
case'red':
return['apple','strawberry'];
case'yellow':
return['banana','pineapple'];
case'purple':
return['grape','plum'];
default:
return[];
}
}
//testresults
test(null);//[]
test('yellow');//['banana','pineapple']
上面的代码看起来没有错误,但是我找到了一些累赘。用对象遍历实现相同的结果,语法看起来更简洁:
constfruitColor={
red:['apple','strawberry'],
yellow:['banana','pineapple'],
purple:['grape','plum']
};
functiontest(color){
returnfruitColor[color]||[];
}
或者你也可以使用Map实现相同的结果:
constfruitColor=newMap()
.set('red',['apple','strawberry'])
.set('yellow',['banana','pineapple'])
.set('purple',['grape','plum']);
functiontest(color){
returnfruitColor.get(color)||[];
}
Map是一种在ES2015规范之后实现的对象类型,允许你存储key和value的值。
但我们是否应当禁止switch语句的使用呢?答案是不要限制你自己。从个人来说,我会尽可能的使用对象遍历,但我并不严格遵守它,而是使用对当前的场景更有意义的方式。
ToddMotto有一篇关于switch语句对比对象遍历的更深入的文章,你可以在这个地方阅读
TL;DR;重构语法
在上面的例子,我们能够用Array.filter重构我们的代码,实现相同的效果。
constfruits=[
{name:'apple',color:'red'},
{name:'strawberry',color:'red'},
{name:'banana',color:'yellow'},
{name:'pineapple',color:'yellow'},
{name:'grape',color:'purple'},
{name:'plum',color:'purple'}
];
functiontest(color){
returnfruits.filter(f=>f.color==color);
}
有着不止一种方法能够实现相同的结果,我们以上展示了4种。
5、对所有/部分判断使用Array.every&Array.some
这***一个建议更多是关于利用JavaScriptArray的内置方法来减少代码行数。看下面的代码,我们想要检查是否所有水果都是红色:
constfruits=[
{name:'apple',color:'red'},
{name:'banana',color:'yellow'},
{name:'grape',color:'purple'}
];
functiontest(){
letisAllRed=true;
//条件:所有水果都是红色
for(letfoffruits){
if(!isAllRed)break;
isAllRed=(f.color=='red');
}
console.log(isAllRed);//false
}
代码那么长!我们可以通过Array.every减少代码行数:
constfruits=[
{name:'apple',color:'red'},
{name:'banana',color:'yellow'},
{name:'grape',color:'purple'}
];
functiontest(){
constisAllRed=fruits.every(f=>f.color=='red');
console.log(isAllRed);//false
}
现在更简洁了,不是吗?相同的方式,如果我们想测试是否存在红色的水果,我们可以使用Array.some一行代码实现。
constfruits=[
{name:'apple',color:'red'},
{name:'banana',color:'yellow'},
{name:'grape',color:'purple'}
];
functiontest(){
//条件:任何一个水果是红色
constisAnyRed=fruits.some(f=>f.color=='red');
console.log(isAnyRed);//true
}
6、总结
让我们一起生产更多可读性高的代码。我希望你能从这篇文章学到东西。
这就是所有的内容。编码快乐!
非本网作品均来自互联网,转载目的在于传递更多信息,并不**本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其他问题,请及时与本网联系,我们将及时删除内容。