JavaScript中条件语句的优化技巧总结


Posted in Javascript onDecember 04, 2020

对多个条件使用 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');
 }
}

我们将条件提取到一个数组中。这样做之后,代码看起来更整洁。

更少的嵌套,尽早返回

扩展前面的示例,以包含另外两个条件:

如果没有提供水果(名称),抛出错误。

如果(红色水果)数量超过 10 个,接受并打印。

看看上面的代码,我们有:

1 组过滤无效条件的 if/else 语句

3层的 if 嵌套语句(条件 1、2 和 3)

遵循的一般规则是,当发现无效条件时,提前返回。

/_ 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');
 }
 }
}

这样,我们就少了一层嵌套。这种编码风格很好,尤其是当你有很长的 if 语句时(想象一下,你需要滚动到最底部才能知道还有一个 else 语句,这并不好)。

通过反转条件和提早返回,我们可以进一步减少嵌套。看看下面的条件 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');
 }
}

通过反转条件 2 的条件,我们的代码现在没有嵌套语句。当我们有很长的逻辑要处理时,这种技术是有用的,当一个条件没有满足时,我们想要停止进一步的处理。

然而,这并不是严格的规则。问问自己,这个版本(没有嵌套)是否比前一个版本(嵌套的条件 2)更好、更易读?

对于我来说,我将把它保留为以前的版本(条件 2 和嵌套)。这是因为:
代码简短而直接,如果嵌套,代码就更清晰了,反转条件可能会导致更多的思考过程(增加认知负担)!

因此,总是以更少的嵌套及尽早返回为目标,但不要过度。

使用默认的函数参数和解构

在使用 JavaScript 时总是需要检查 null 或 undefined 值并分配默认值:

function test(fruit, quantity) {
 if (!fruit) return;
 const q = quantity || 1; 
}

//test results
test('banana');
test('apple', 2);

事实上,可以通过指定默认的函数参数来消除变量 q。

function test(fruit, quantity = 1) {
 if (!fruit) return;
}

//test results
test('banana');
test('apple', 2);

请注意,每个参数都可以有自己的默认函数参数。例如,我们也可以为 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。我们可以避免使用与默认函数参数和解构对条件 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} 来解构,然后我们可以在代码中使用 name 作为变量,而不是 fruit.name。

我们还将空对象 {} 指定为默认值。如果我们不这样做,当执行 test(undefined),不能解构 undefined 或 null 的属性名时,您将会得到错误。因为在 undefined中没有 name 属性。

选择 Map 或对象字面量,而不是 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']

上面的代码似乎没有什么问题,但发现它相当冗长。同样的结果可以通过对象字面量和更简洁的语法来实现:

const fruitColor = {
  red: ['apple', 'strawberry'],
  yellow: ['banana', 'pineapple'],
  purple: ['grape', 'plum']
 };
 
function test(color) {
 return fruitColor[color] || [];
}

或者,可以使用 Map 来实现相同的结果:

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 以后可用的对象类型,允许您存储键值对。

对于上面的示例,我们实际上可以重构代码,以使用 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) {
 // use Array filter to find fruits in color
 
 return fruits.filter(f => f.color == color);
}

总有不止一种方法可以达到同样的效果。展示了 4 个相同效果的例子。

所有或部分使用 Array.every & Array.some 的条件

使用新的Javascript 数组函数来减少代码行。看看下面的代码,我们想检查所有的水果是否都是红色的:

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 来减少行数:

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
}

现在干净多了,对吧?类似地,如果我们想用一行代码来判断任何一个水果是否为红色,我们可以使用 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
}

到此这篇关于JavaScript中条件语句的优化技巧的文章就介绍到这了,更多相关JS条件语句优化技巧内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
5款Javascript颜色选择器
Oct 25 Javascript
js自定义事件代码说明
Jan 31 Javascript
jQuery中$.each使用详解
Jan 29 Javascript
dedecms页面如何获取会员状态的实例代码
Mar 15 Javascript
论Bootstrap3和Foundation5网格系统的异同
May 16 Javascript
浅谈jQuery 中的事件冒泡和阻止默认行为
May 28 Javascript
Javascript OOP之面向对象
Jul 31 Javascript
javascript实现获取指定精度的上传文件的大小简单实例
Oct 25 Javascript
深入理解ES6 Promise 扩展always方法
Sep 26 Javascript
node.js将MongoDB数据同步到MySQL的步骤
Dec 10 Javascript
vue中改变选中当前项的显示隐藏或者状态的实现方法
Feb 08 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
Feb 26 Javascript
三剑客:offset、client和scroll还傻傻分不清?
Dec 04 #Javascript
简单谈谈offsetleft、offsetTop和offsetParent
Dec 04 #Javascript
HTML元素拖拽功能实现的完整实例
Dec 04 #Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
Dec 04 #Vue.js
vue基于Echarts的拖拽数据可视化功能实现
Dec 04 #Vue.js
addEventListener()和removeEventListener()追加事件和删除追加事件
Dec 04 #Javascript
vue使用echarts图表自适应的几种解决方案
Dec 04 #Vue.js
You might like
PHP 替换模板变量实现步骤
2009/08/24 PHP
CI框架中$this->load->library()用法分析
2016/05/18 PHP
PHP大文件切割上传并带进度条功能示例
2019/07/01 PHP
为JavaScript提供睡眠功能(sleep) 自编译JS引擎
2010/08/16 Javascript
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
使用闭包对setTimeout进行简单封装避免出错
2013/07/10 Javascript
javascript折半查找详解
2015/01/26 Javascript
jquery使用remove()方法删除指定class子元素
2015/03/26 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
js实现选项卡内容切换以及折叠和展开效果【推荐】
2017/01/08 Javascript
Vue实现自带的过滤器实例
2017/03/09 Javascript
ES6新特性七:数组的扩充详解
2017/04/21 Javascript
Vue input控件通过value绑定动态属性及修饰符的方法
2017/05/03 Javascript
vue axios请求拦截实例代码
2018/03/29 Javascript
mpvue中使用flyjs全局拦截的实现代码
2018/09/13 Javascript
layer.confirm点击第一个按钮关闭弹出框的方法
2019/09/09 Javascript
vue配置nprogress实现页面顶部进度条
2019/09/21 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
Webpack的Loader和Plugin的区别
2020/11/09 Javascript
Python常用模块用法分析
2014/09/08 Python
Python中的ctime()方法使用教程
2015/05/22 Python
python贪婪匹配以及多行匹配的实例讲解
2018/04/19 Python
python让列表倒序输出的实例
2018/06/25 Python
搞清楚 Python traceback的具体使用方法
2019/05/13 Python
matplotlib教程——强大的python作图工具库
2020/10/15 Python
Django模板报TemplateDoesNotExist异常(亲测可行)
2020/12/18 Python
学生个人求职自荐信格式
2013/09/23 职场文书
大学生简历中个人的自我评价
2013/10/06 职场文书
4s店销售经理岗位职责
2014/07/19 职场文书
股东授权委托书范本
2014/09/13 职场文书
运动会广播稿50字-100字
2014/10/11 职场文书
领导干部“四风”查摆问题个人整改措施
2014/10/28 职场文书
刑事上诉状(量刑过重)
2015/05/23 职场文书
2015年度招聘工作总结
2015/05/28 职场文书
python实现对doc、txt、xls等文档的读写操作
2022/04/02 Python
Nginx利用Logrotate实现日志分割
2022/05/20 Servers