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 相关文章推荐
JavaScript Distilled 基础知识与函数
Apr 07 Javascript
js实现局部页面打印预览原理及示例代码
Jul 03 Javascript
JavaScript实现LI列表数据绑定的方法
Aug 04 Javascript
jQuery实现Flash效果上下翻动的中英文导航菜单代码
Sep 22 Javascript
页面内容排序插件jSort使用方法
Oct 10 Javascript
react开发中如何使用require.ensure加载es6风格的组件
May 09 Javascript
jquery实现联想词搜索框和搜索结果分页的示例
Oct 10 jQuery
微信小程序云开发(数据库)详解
May 17 Javascript
浅谈bootstrap layer.open中end的使用方法
Sep 12 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
Feb 15 Javascript
深入了解JavaScript词法作用域
Jul 29 Javascript
如何在JavaScript中正确处理变量
Dec 25 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
长波知识介绍
2021/03/01 无线电
PHP中strtotime函数使用方法分享
2012/01/10 PHP
探讨php中防止SQL注入最好的方法是什么
2013/06/10 PHP
PHP开发工具ZendStudio下Xdebug工具使用说明详解
2013/11/11 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
PHP延迟静态绑定的深入讲解
2018/04/02 PHP
收藏一些不常用,但是有用的代码
2007/03/12 Javascript
再谈javascript面向对象编程
2012/03/18 Javascript
javascript中关于break,continue的特殊用法与介绍
2012/05/24 Javascript
基于JavaScript实现继承机制之原型链(prototype chaining)的详解
2013/05/07 Javascript
JS 如何获取radio选中后的值及不选择取radio的值
2013/10/28 Javascript
实现无刷新联动例子汇总
2015/05/20 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
chrome调试javascript详解
2015/10/21 Javascript
JavaScript队列函数和异步执行详解
2017/06/19 Javascript
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
2017/09/20 jQuery
vue组件间通信子与父详解(二)
2017/11/07 Javascript
微信小程序使用picker实现时间和日期选择框功能【附源码下载】
2017/12/11 Javascript
Vue.directive 自定义指令的问题小结
2018/03/04 Javascript
JS数组Reduce方法功能与用法实例详解
2020/04/29 Javascript
写了个监控nginx进程的Python脚本
2012/05/10 Python
python迭代器实例简析
2014/09/25 Python
全面了解Python环境配置及项目建立
2016/06/30 Python
Python cookbook(数据结构与算法)实现查找两个字典相同点的方法
2018/02/18 Python
Python生成器定义与简单用法实例分析
2018/04/30 Python
Django REST framework 如何实现内置访问频率控制
2019/07/23 Python
浅谈keras通过model.fit_generator训练模型(节省内存)
2020/06/17 Python
Python如何telnet到网络设备
2021/02/18 Python
绩效专员岗位职责
2013/12/02 职场文书
超市业务员岗位职责
2013/12/05 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
企业财务总监岗位职责
2015/04/03 职场文书
采购内勤岗位职责
2015/04/13 职场文书
2015年学生资助工作总结
2015/05/25 职场文书
导游词之临安白水涧
2019/11/05 职场文书
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电