11个Javascript小技巧帮你提升代码质量(小结)


Posted in Javascript onDecember 28, 2020

本文会不断更新,不足之处欢迎评论区补充。

1. 提炼函数

好处:

  • 避免出现超大函数。
  • 独立出来的函数有助于代码复用。
  • 独立出来的函数更容易被覆写。
  • 独立出来的函数如果拥有一个良好的命名,它本身就起到了注释的作用。
  • 语义化将多段分离的逻辑放在不同的函数中实现,可以使代码逻辑清晰,清楚的看到每一步在做什么。

代码举例:

实现获取数据,然后操作dom显示数据,最后添加事件

函数提炼前

// 逻辑都写在一起,需要将所有逻辑看完才知道这段代码是干嘛的,局部逻辑无法复用
function main() {
 $.ajax.get('/getData').then((res) => {
  const ul = document.getElementById('ul');
  ul.innerHTML = res.list.map(text => `<li class="li">${text}</li>`).join('\n');
  const list = document.getElementsByClassName('li');
  for (let i = 0; i < list.length; i ++) {
   list[i].addEventListener('focus', () => {
    // do something
   });
  }
 });
}

函数提炼后

function getData() {
 return $.ajax.get('/getData').then((res) => res.data.list);
}
function showList(list) {
 const ul = document.getElementById('ul');
 ul.innerHTML = list.map(text => `<li class="li">${text}</li>`).join('\n');
}
function addEvent() {
 const list = document.getElementsByClassName('li');
 for (let i = 0; i < list.length; i ++) {
  list[i].addEventListener('focus', () => {
   // do something
  });
 }
}
// 逻辑清晰,一眼读懂每一步在做什么,某些提炼出来的函数还可以被复用
async function main() {
 const list = await getData(); // 获取数据
 showList(list); // 显示页面
 addEvent(); // 添加事件
}

2. 合并重复的条件片段

如果一个函数体内有一些条件分支语句,而这些条件分支语句内部散布了一些重复的代码,那么就有必要进行合并去重工作。

// 合并前
function main( currPage ){
 if ( currPage <= 0 ){
  currPage = 0;
  jump( currPage ); // 跳转
 }else if ( currPage >= totalPage ){
  currPage = totalPage;
  jump( currPage ); // 跳转
 }else{
  jump( currPage ); // 跳转
 }
};

// 合并后
function main( currPage ){
 if ( currPage <= 0 ){
  currPage = 0;
 }else if ( currPage >= totalPage ){
  currPage = totalPage;
 }
 jump( currPage ); // 把jump 函数独立出来
};

3. 把条件分支语句提炼成函数

复杂的条件分支语句是导致程序难以阅读和理解的重要原因,而且容易导致一个庞大的函数。有时可以将条件分支语句提炼成语义化的函数,使代码更加直观,逻辑清晰。

// 根据不同季节决定打折力度
function getPrice( price ){
 var date = new Date();
 if ( date.getMonth() >= 6 && date.getMonth() <= 9 ){ // 夏天
  return price * 0.8;
 }
 return price;
};


// 是否是夏天
function isSummer(){
 var date = new Date();
 return date.getMonth() >= 6 && date.getMonth() <= 9;
};
// 提炼条件后
function getPrice( price ){
 if ( isSummer() ){
  return price * 0.8;
 }
 return price;
};

4. 合理使用循环

如果多段代码实际上负责的是一些重复性的工作,那么可以用循环代替,使代码量更少。

// 判断是什么浏览器
function getBrowser(){
 const str = navigator.userAgent;
 if (str.includes('QQBrowser')) {
 return 'qq';
 } else if (str.includes('Chrome')) {
 return 'chrome';
 } else if (str.includes('Safari')) {
  return 'safri';
 } else if (str.includes('Firefox')) {
  return 'firefox';
 } else if(explorer.indexOf('Opera') >= 0){
  return 'opera';
 } else if (str.includes('msie')) {
  return 'ie';
 } else {
  return 'other';
 }
};


// 循环判断,将对应关系抽象为配置,更加清晰明确
function getBrowser(){
 const str = navigator.userAgent;
 const list = [
  {key: 'QQBrowser', browser: 'qq'},
  {key: 'Chrome', browser: 'chrome'},
  {key: 'Safari', browser: 'safari'},
  {key: 'Firefox', browser: 'firefox'},
  {key: 'Opera', browser: 'opera'},
  {key: 'msie', browser: 'ie'},
 ];
 for (let i = 0; i < list.length; i++) {
  const item = list[i];
  if (str.includes(item.key)) {return item.browser};
 }
 return 'other';
}

5. 提前让函数退出代替嵌套条件分支

让函数变成多出口提前返回,替换嵌套条件分支。

function del( obj ){
 var ret;
 if ( !obj.isReadOnly ){ // 不为只读的才能被删除
  if ( obj.isFolder ){ // 如果是文件夹
   ret = deleteFolder( obj );
  }else if ( obj.isFile ){ // 如果是文件
   ret = deleteFile( obj );
  }
 }
 return ret;
};

function del( obj ){
 if ( obj.isReadOnly ){ // 反转if 表达式
  return;
 }
 if ( obj.isFolder ){
  return deleteFolder( obj );
 }
 if ( obj.isFile ){
  return deleteFile( obj );
 }
};

6. 传递对象参数代替过长的参数列表

函数参数过长那么就增加出错的风险,想保证传递的顺序正确就是一件麻烦的事,代码可读性也会变差,尽量保证函数的参数不会太长。如果必须传递多个参数的话,建议使用对象代替。

一般来说,函数参数最好不要超过3个

function setUserInfo( id, name, address, sex, mobile, qq ){
 console.log( 'id= ' + id );
 console.log( 'name= ' +name );
 console.log( 'address= ' + address );
 console.log( 'sex= ' + sex );
 console.log( 'mobile= ' + mobile );
 console.log( 'qq= ' + qq );
};
setUserInfo( 1314, 'sven', 'shenzhen', 'male', '137********', 377876679 );

function setUserInfo( obj ){
 console.log( 'id= ' + obj.id );
 console.log( 'name= ' + obj.name );
 console.log( 'address= ' + obj.address );
 console.log( 'sex= ' + obj.sex );
 console.log( 'mobile= ' + obj.mobile );
 console.log( 'qq= ' + obj.qq );
};
setUserInfo({
 id: 1314,
 name: 'sven',
 address: 'shenzhen',
 sex: 'male',
 mobile: '137********',
 qq: 377876679
});

7. 少用三目运算符

三目运算符性能高,代码量少。
但不应该滥用三目运算符,我们应该在简单逻辑分支使用,在复杂逻辑分支避免使用。

// 简单逻辑可以使用三目运算符
var global = typeof window !== "undefined" ? window : this;

// 复杂逻辑不适合使用
var ok = isString ? (isTooLang ? 2 : (isTooShort ? 1 : 0)) : -1;

8. 合理使用链式调用

优点:
链式调用使用简单,代码量少。

缺点:
链式调用带来的坏处就是在调试不方便,如果我们知道一条链中有错误出现,必须得先把这条链拆开才能加上一些调试 log 或者增加断点,这样才能定位错误出现的地方。

如果该链条的结构相对稳定,后期不易发生修改,可以使用链式。

var User = {
 id: null,
 name: null,
 setId: function( id ){
  this.id = id;
  return this;
 },
 setName: function( name ){
  this.name = name;
  return this;
 }
};
User
 .setId( 1314 )
 .setName( 'sven' );

var user = new User();
user.setId( 1314 );
user.setName( 'sven' );

9. 分解大型类

大型类的分解和函数的提炼很像,类太大会出现逻辑不清晰,难以理解和维护的问题。
合理的大类分解可以使类的逻辑清晰,且子模块可以方便复用。

10. 活用位操作符

编程语言计算乘除的性能都不高,但是某些情况使用位操作符可以提升乘除等运算的性能。

11. 纯函数

纯函数是指不依赖于且不改变它作用域之外的变量状态的函数。
纯函数的返回值只由它调用时的参数决定,它的执行不依赖于系统的状态(执行上下文)。
相同的输入参数,一定会得到相同的输出,也就是内部不含有会影响输出的随机变量。

不属于纯函数的特点:

  • 更改文件系统
  • 往数据库插入记录
  • 发送一个 http 请求
  • 可变数据
  • 打印/log
  • 获取用户输入
  • DOM 查询
  • 访问系统状态

纯函数的作用:

  • 可靠性:函数返回永远和预期一致
  • 可缓存性:因为只要输入一样输出一定一样,因此可将输入作为key,输出作为值,使用对象缓存已经计算的结果
  • 可移植性:因为没有外部依赖,所以移植到任何环境都可正确运行
  • 可测试性:方便针对函数做单元测试
  • 可并行性:对一些复杂计算,可以并行计算(例如使用nodejs多个子进程同时并行计算多个任务,提高计算速度)

应用场景:

  • 工具函数最好使用纯函数
  • 多平台使用的代码(nodejs、浏览器、微信小程序、native客户端等)
  • 相对独立的功能
var a = 1;
// 非纯函数
function sum(b) {
 return a + b;
}
// 非纯函数
function sum(b) {
 a = 2;
 return b;
}
// 非纯函数
function sum(b) {
 return b + Math.random();
}


// 纯函数
function sum (b, c) {
 return b + c;
}

参考

JavaScript设计模式与开发实践

到此这篇关于11个Javascript小技巧帮你提升代码质量(小结)的文章就介绍到这了,更多相关Javascript 提升代码质量内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
避免 showModalDialog 弹出新窗体的原因分析
May 31 Javascript
jquery与prototype框架的详细对比
Nov 21 Javascript
jquery checkbox实现单选小例
Nov 27 Javascript
纯js和css实现渐变色包括静态渐变和动态渐变
May 29 Javascript
让javascript加载速度倍增的方法(解决JS加载速度慢的问题)
Dec 12 Javascript
深入探究AngularJS框架中Scope对象的超级教程
Jan 04 Javascript
利用CSS、JavaScript及Ajax实现图片预加载的三大方法
Jan 22 Javascript
mpvue 单文件页面配置详解
Dec 02 Javascript
js+html实现周岁年龄计算器
Jun 25 Javascript
JavaScript自动生成 年月范围 选择功能完整示例【基于jQuery插件】
Sep 03 jQuery
JavaScript实现随机五位数验证码
Sep 27 Javascript
JavaScript实现通讯录功能
Dec 27 Javascript
vue中watch的用法汇总
Dec 28 #Vue.js
浅析vue中的nextTick
Dec 28 #Vue.js
js仿淘宝放大镜效果
Dec 28 #Javascript
JavaScript实现原型封装轮播图
Dec 27 #Javascript
JavaScript代码实现简单计算器
Dec 27 #Javascript
JavaScript实现雪花飘落效果
Dec 27 #Javascript
微信小程序自定义胶囊样式
Dec 27 #Javascript
You might like
php下将XML转换为数组
2010/01/01 PHP
浅析PHP程序防止ddos,dns,集群服务器攻击的解决办法
2013/06/18 PHP
CI框架安全类Security.php源码分析
2014/11/04 PHP
Yii实现MySQL多数据库和读写分离实例分析
2014/12/03 PHP
php猜单词游戏
2015/09/29 PHP
php禁用cookie后session设置方法分析
2016/10/19 PHP
thinkPHP框架对接支付宝即时到账接口回调操作示例
2016/11/14 PHP
给Function做的OOP扩展
2009/05/07 Javascript
JavaScript效率调优经验
2009/06/04 Javascript
jQuery 表单验证扩展代码(一)
2010/10/11 Javascript
浅谈JavaScript中定义变量时有无var声明的区别
2014/08/18 Javascript
原生javascript获取元素样式
2014/12/31 Javascript
Nodejs学习笔记之测试驱动
2015/04/16 NodeJs
js实现的简单图片浮动效果完整实例
2016/05/10 Javascript
Vue组件开发初探
2017/02/14 Javascript
微信小程序实现图片上传功能
2018/05/28 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
vuex管理状态 刷新页面保持不被清空的解决方案
2019/11/11 Javascript
Javascript实现html转pdf高清版(提高分辨率)
2020/02/19 Javascript
微信小程序学习总结(二)样式、属性、模板操作分析
2020/06/04 Javascript
vue+Element-ui前端实现分页效果
2020/11/15 Javascript
vite2.0+vue3移动端项目实战详解
2021/03/03 Vue.js
[57:53]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#3OG VS VP
2016/03/03 DOTA
Python3实现取图片中特定的像素替换指定的颜色示例
2019/01/24 Python
使用python实现抓取腾讯视频所有电影的爬虫
2019/04/15 Python
Django继承自带user表并重写的例子
2019/11/18 Python
python如何基于redis实现ip代理池
2020/01/17 Python
租租车:国际租车、美国租车、欧洲租车、特价预订国外租车(中文服务)
2018/03/28 全球购物
师范生实习个人的自我评价
2013/09/28 职场文书
关爱留守儿童倡议书
2014/04/15 职场文书
希特勒的演讲稿
2014/05/23 职场文书
通讯稿格式及范文
2015/07/22 职场文书
导游词之天下银坑景区
2019/11/21 职场文书
Matlab求解数组中的最大值及它所在的具体位置
2021/04/16 Python
详解Mysql和Oracle之间的误区
2021/05/18 MySQL
使用python+pygame开发消消乐游戏附完整源码
2021/06/10 Python