来自公众号:小生方勤

作者:小生方勤

如何提高代码的可读性、复用性、扩展性。我们将从以下四个方面讨论:

  1. 变量

  2. 函数

  3. 异步

一、变量

用有意义且常用的单词命名

// Bad:
const yyyymmdstr = moment().format('YYYY/MM/DD');
// Good:
const currentDate = moment().format('YYYY/MM/DD');

保持统一

对同一类型的变量使用相同的命名保持统一:

// Bad:
getUserInfo();
getClientData();
getCustomerRecord();
// Good:
getUser()

每个常量(全大写)都该命名

可以用 ESLint 检测代码中未命名的常量。

// Bad:
// 其他人知道 86400000 的意思吗?
setTimeout( blastOff, 86400000 );
// Good:
const MILLISECOND_IN_A_DAY = 86400000;
setTimeout( blastOff, MILLISECOND_IN_A_DAY );

避免无意义的前缀

如果创建了一个对象 car,就没有必要把它的颜色命名为 carColor。

// Bad:
const car = {carMake: 'Honda',carModel: 'Accord',carColor: 'Blue'
};
function paintCar( car ) {car.carColor = 'Red';
}
// Good:
const car = {make: 'Honda',model: 'Accord',color: 'Blue'
};
function paintCar( car ) {car.color = 'Red';
}

传参使用默认值

// Bad:
function createMicrobrewery( name ) {const breweryName = name || 'Hipster Brew Co.';// ...
}
// Good:
function createMicrobrewery( name = 'Hipster Brew Co.' ) {// ...
}

二、函数

函数参数( 最好 2 个或更少 )

如果参数超过两个,建议使用 ES6 的解构语法,不用考虑参数的顺序。

// Bad:
function createMenu( title, body, buttonText, cancellable ) {// ...
}
// Good:
function createMenu( { title, body, buttonText, cancellable } ) {// ...
}
createMenu({title: 'Foo',body: 'Bar',buttonText: 'Baz',cancellable: true
});

一个方法只做一件事情

这是一条在软件工程领域流传久远的规则。严格遵守这条规则会让你的代码可读性更好,也更容易重构。如果违反这个规则,那么代码会很难被测试或者重用。

// Bad:
function emailClients( clients ) {clients.forEach( client => {const clientRecord = database.lookup( client );if ( clientRecord.isActive() ) {email( client );}});
}
// Good:
function emailActiveClients( clients ) {clients.filter( isActiveClient ).forEach( email );
}
function isActiveClient( client ) {const clientRecord = database.lookup( client );    return clientRecord.isActive();
}

函数名上体现它的作用

// Bad:
function addToDate( date, month ) {// ...
}
const date = new Date();
// 很难知道是把什么加到日期中
addToDate( date, 1 );
// Good:
function addMonthToDate( month, date ) {// ...
}
const date = new Date();
addMonthToDate( 1, date );

删除重复代码,合并相似函数

很多时候虽然是同一个功能,但由于一两个不同点,让你不得不写两个几乎相同的函数。

// Bad:
function showDeveloperList(developers) {developers.forEach((developer) => {const expectedSalary = developer.calculateExpectedSalary();const experience = developer.getExperience();const githubLink = developer.getGithubLink();const data = {expectedSalary,experience,githubLink};render(data);});
}
function showManagerList(managers) {managers.forEach((manager) => {const expectedSalary = manager.calculateExpectedSalary();const experience = manager.getExperience();const portfolio = manager.getMBAProjects();const data = {expectedSalary,experience,portfolio};render(data);});
}
// Good:
function showEmployeeList(employees) {employees.forEach(employee => {const expectedSalary = employee.calculateExpectedSalary();const experience = employee.getExperience();const data = {expectedSalary,experience,};switch(employee.type) {case 'develop':data.githubLink = employee.getGithubLink();breakcase 'manager':data.portfolio = employee.getMBAProjects();break}render(data);})
}

使用 Object.assign 设置默认属性

// Bad:
const menuConfig = {title: null,body: 'Bar',buttonText: null,cancellable: true
};
function createMenu(config) {config.title = config.title || 'Foo';config.body = config.body || 'Bar';config.buttonText = config.buttonText || 'Baz';config.cancellable = config.cancellable !== undefined ? config.cancellable : true;
}
createMenu(menuConfig);
// Good:
const menuConfig = {title: 'Order',// 不包含 bodybuttonText: 'Send',cancellable: true
};
function createMenu(config) {config = Object.assign({title: 'Foo',body: 'Bar',buttonText: 'Baz',cancellable: true}, config);// config : {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}// ...
}
createMenu(menuConfig);

尽量不要写全局方法

在 JavaScript 中,永远不要污染全局,会在生产环境中产生难以预料的 bug。举个例子,比如你在 Array.prototype 上新增一个 diff 方法来判断两个数组的不同。而你同事也打算做类似的事情,不过他的 diff 方法是用来判断两个数组首位元素的不同。很明显你们方法会产生冲突,遇到这类问题我们可以用 ES2015/ES6 的语法来对 Array 进行扩展。

// Bad:
Array.prototype.diff = function diff(comparisonArray) {const hash = new Set(comparisonArray);return this.filter(elem => !hash.has(elem));
};
// Good:
class SuperArray extends Array {diff(comparisonArray) {const hash = new Set(comparisonArray);return this.filter(elem => !hash.has(elem));        }
}

尽量别用“非”条件句

// Bad:
function isDOMNodeNotPresent(node) {// ...
}
if (!isDOMNodeNotPresent(node)) {// ...
}
// Good:
function isDOMNodePresent(node) {// ...
}
if (isDOMNodePresent(node)) {// ...
}

不要过度优化

现代浏览器已经在底层做了很多优化,过去的很多优化方案都是无效的,会浪费你的时间。

// Bad:
// 现代浏览器已对此( 缓存 list.length )做了优化。
for (let i = 0, len = list.length; i < len; i++) {// ...
}
// Good:
for (let i = 0; i < list.length; i++) {// ...
}

删除弃用代码

这里没有实例代码,删除就对了

三、类

使用 ES6 的 class

在 ES6 之前,没有类的语法,只能用构造函数的方式模拟类,可读性非常差。

// Good:
// 动物
class Animal {constructor(age) {this.age = age};move() {};
}
// 哺乳动物
class Mammal extends Animal{constructor(age, furColor) {super(age);this.furColor = furColor;};liveBirth() {};
}
// 人类
class Human extends Mammal{constructor(age, furColor, languageSpoken) {super(age, furColor);this.languageSpoken = languageSpoken;};speak() {};
}

使用链式调用

这种模式相当有用,可以在很多库中都有使用。它让你的代码简洁优雅。

class Car {constructor(make, model, color) {this.make = make;this.model = model;this.color = color;}setMake(make) {this.make = make;}setModel(model) {this.model = model;}setColor(color) {this.color = color;}save() {console.log(this.make, this.model, this.color);}
}
// Bad:
const car = new Car('Ford','F-150','red');
car.setColor('pink');
car.save();
// Good:
const car = new Car('Ford','F-150','red').setColor('pink');.save();

四、异步

使用 promise 或者 Async/Await 代替回调

// Bad:
get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin', (requestErr, response) => {if (requestErr) {console.error(requestErr);} else {writeFile('article.html', response.body, (writeErr) => {if (writeErr) {console.error(writeErr);} else {console.log('File written');}});}
});
// Good:
get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin').then((response) => {return writeFile('article.html', response);}).then(() => {console.log('File written');}).catch((err) => {console.error(err);});// perfect:
async function getCleanCodeArticle() {try {const response = await get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin');await writeFile('article.html', response);console.log('File written');} catch(err) {console.error(err);}
}

❤️爱心三连击
1.看到这里了就点个在看支持下吧,你的「点赞,在看」是我创作的动力。
2.关注公众号程序员成长指北,回复「1」加入高级前端交流群!「在这里有好多 前端 开发者,会讨论 前端 Node 知识,互相学习」!
3.也可添加微信【ikoala520】,一起成长。“在看转发”是最大的支持

这样写的 JS 代码看着就很舒服相关推荐

  1. js array formdata_这样写的 JS 代码看着就很舒服

    来自公众号:小生方勤 作者:小生方勤 如何提高代码的可读性.复用性.扩展性.我们将从以下四个方面讨论: 变量 函数 类 异步 一.变量 用有意义且常用的单词命名 // Bad:const yyyymm ...

  2. 有一种女人,她们并不漂亮,但看上去却很舒服!

    有一种女人, 她们并不漂亮, 但看上去却很舒服! 在日常生活中, 我经常会碰到这样一种女人, 她们并不漂亮, 但看上去却很舒服. 有着为人母的慈爱, 为人妻的贤淑. 一举一动里透出涵养. 聪慧与贤达. ...

  3. python一看就很厉害的代码_Python学习教程:怎么写出让人看起来就很舒服的代码?...

    Python学习教程:怎么写出让人看起来很优雅舒服的代码?让人眼前一亮! 很多新手在开始学一门新的语言的时候,往往会忽视一些不应该忽视的细节,比如变量命名和函数命名以及注释等一些内容的规范性,久而久之 ...

  4. 你知道吗?JS代码混淆加密,很有用!

    JS代码为什么要进行混淆加密? 因为:JS代码是明文. JS是种开放源码的编程语言, 无论是前端浏览器中的JS代码,还是在后端使用,如nodejs,js代码都是明文, 明文代码,他人可以随意查看.复制 ...

  5. 使用processing编译器写p5.js代码

    1.打开processing编译器,点击右上角Jav的下拉小箭头 2.选择添加模式进入如下界面,在上方菜单栏选择Modes,在屏幕中选P5.js一项,点击右下角installed.3.安装完成后返回, ...

  6. 最新爆笑段子120个,看了心境很舒服的噢(转吧转吧!)

    59.孔子曰,中午不睡,下战书瓦解:孟子曰,孔子说的对  60.9个橙子分给13个小友人,怎么分才公正?-杀死4个小朋友.  61.假如她(他)对你说:"忘了我吧."你告知对方:& ...

  7. Angular4中调用js代码

    转自 引言:Angular2开始采用TypeScript进行编码.本文讲述如何在Angular4项目中调用原生的 js 代码. 本文代码 代码使用环境:webstrom 调用过程可以归纳为: 引入 j ...

  8. 【Js】【调试】VSCode中调试Js代码

      以前调试一段js代码总是会将js代码嵌入html页面,然后利用浏览器的开发者工具打断点来调试js代码,感觉还是有一点麻烦,想着直接在vscode中调试一个js代码那不就很方便了吗.   vscod ...

  9. $.post请求的参数在后台代码中得到为null_996难得休息,小伙打开steam网页看了一款游戏,输入密码后却习惯性按了F12研究起了JS代码...

    登录后才能获取数据也是现在反爬的一个重点,本期我们来看看两种登录方式,分别参考豆瓣与steam,由于js代码过长,所以只截取了部分,完整代码移步 从今天开始种树​www.happyhong.cn ,直 ...

最新文章

  1. 微软发布 Mobile Express for Microsoft Dynamics CRM 4.0
  2. 【Node.js】http-server 实现目录浏览服务
  3. [转] java.nio.ByteBuffer中flip、rewind、clear方法的区别
  4. 人工智能生态环境预测_2020年全球人工智能芯片发展趋势及市场规模预测
  5. @@IDENTITY与SCOPE_IDENTITY()
  6. java day32【HTML标签:表单标签 、CSS】
  7. 人工智能-baidu-aip语音识别(语音转文字)
  8. javawebJSP餐厅点餐系统源码JSP点餐系统JSP网上订餐系统JSP在线订餐系统JSP外卖系统
  9. 【游记】CQOI2021
  10. 新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)
  11. 深度学习图像算法在内容安全领域的应用
  12. DB2表空间状态列表
  13. Windows 7 Build 7068 下载泄露
  14. html实现点击图片全屏显示,用vue实现点击图片预览浏览器满屏大图
  15. Cannot read lifecycle mapping metadata for artifact org.apache.maven.plugins:mav问题
  16. jQuery中过滤选择器的eq,ne等于gt大于lt小于
  17. 构造方法可以被private修饰么?
  18. 第九节 Shiro标签原理分析
  19. buuctf-[CISCN2019 总决赛 Day2 Web1]Easyweb
  20. OceanBase Developer Center

热门文章

  1. DFS理解(java)
  2. KVM虚拟机转移到ESXI6.5
  3. java高级架构师的自我修养;文末有进阶路线思维导图
  4. 摄影/秋日花展(二)
  5. 基于 gff 文件构建 TxDb 包
  6. 【信息系统项目管理师】第七章 成本管理思维导图
  7. 【网络通信】【ZeroTier】ZeroTier 的安装与使用
  8. 建设创客教育运动中的完整体系
  9. 《大数据+AI在大健康领域中最佳实践前瞻》---- 以元数据管理角度出发看人工智能医疗器械标准数据集的构建
  10. python-经世优学挂学时脚本2.0