原文:github.com/ryanmcdermott/clean-code-javascript
说明:本文翻译自 github 上的一个项目,只取部分精华。

一、变量

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

//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,864000);
//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.getExpectedSalary();
const experience = employee.getExperience();
const data = {
expectedSalary,
experience,
}
switch(employee.type){
case 'develop':
data.githubLink=employee.getGithubLink();
break;
case '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',
//不包含body
buttonText: '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}
// ...
}

尽量不要写全局方法

在 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 (!isDOMNodePresent(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){
consoloe.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( (response) => {
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('artical.html',response);
console.log('File written');
}catch (err){
console.error(err);
}
}

JS编程规范指南的更多相关文章

  1. JS编程规范

    在第一家公司用C++时,公司有着严格的代码规范,甚至到了严苛的地步,现在回想起来,对它充满感激.一个好的习惯让你收益终身. 之后使用JS/TS却没有为自己定一套编程规范,所幸为时不晚,在这里参考air ...

  2. Node.js编程规范

    摘自:https://github.com/dead-horse/node-style-guide https://github.com/felixge/node-style-guide 2空格缩进 ...

  3. tensorflow2.0编程规范

    背景 tensorflow2.0 相比于1.0 有很大变化,1.0版本的placeholder,Session都没有了,2.0版本强推使用keras.keras是一个比较高层的api,确实挺好用的,一 ...

  4. Batsing的网页编程规范(HTML/CSS/JS/PHP)

    特别注意!!!我这里的前端编程规范不苟同于Bootstrap的前端规范. 因为我和它的目的不同,Bootstrap规范是极简主义,甚至有些没有考虑到兼容性的问题. 我的规范是自己从编程实践中总结出来的 ...

  5. Google的Java编程风格指南(Java编码规范)

    这份文档是Google Java编程风格规范的完整定义.当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合Google的Java编程风格. 与其它的编程风格指南一样,这里所讨论的不仅仅是 ...

  6. .NET编程规范

    .NET开发编程规范 第1章 程序的版式 版式虽然不会影响程序的功能,但会影响可读性.程序的版式追求清晰.美观,是程序风格的重要构成因素. 可以把程序的版式比喻为"书法".好的&q ...

  7. JavaScript编码规范指南

    前言 本文摘自Google JavaScript编码规范指南,截取了其中比较容易理解与遵循的点作为团队的JavaScript编码规范. JavaScript 语言规范 变量 声明变量必须加上 var  ...

  8. Google Java编程风格指南

    出处:http://hawstein.com/posts/google-java-style.html 声明:本文采用以下协议进行授权: 自由转载-非商用-非衍生-保持署名|Creative Comm ...

  9. 谷歌Java编程规范

    Google Java编程风格指南 January 20, 2014 作者:Hawstein 出处:http://hawstein.com/posts/google-java-style.html 声 ...

随机推荐

  1. Updatepanel 中使用 Timer 控件 失去焦点问题

    在Update Panel 中 如果使用timer 定时刷新数据,会造成textbox 或者其他控件的焦点丢失问题. 所以 text box 不能和timer 放在同一个Updatepanel 中. ...

  2. E20190523-h

    evaluate v. 估计; 评价; 评估; substantial  adj. 大量的; 价值巨大的; 重大的; 大而坚固的; 结实的; 牢固的; portion n. 部分; (食物的) 一份, ...

  3. ue4 修改3dui内容

    修改text内容1 修改text内容2 上面的方法是对外公开某个控件,然后再蓝图中直接改控件内容 另一种更好的方法时,在控件上新建public变量,控件绑定到这个变量上,由蓝图直接改变这个public ...

  4. ue4 renderTexture简单记录

    示例内容中的renderTexture 抓取部分 1 新建一个TextureRenderTarget2D 2 抓图 新建actor,一个camera,下面挂一个SceneCaptureComponen ...

  5. 解决webSocke客户端连接服务端返回400错误

    原因: nginx使用了转发,头信息没设置全,问题出现在nginx的配置文件 解决办法: 修改nginx.conf配置文件,在linux终端敲入vim /etc/nginx/nginx.conf,找到 ...

  6. 剑指Offer的学习笔记(C#篇)-- 整数中1出现的次数(从1到n整数中1出现的次数)

    题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...

  7. Awesome Blockchain 区块链技术导航

    区块链技术导航:收集整理最全面最优质的区块链(BlockChain)技术开发相关资源. 以后找不到文档资料的时候去导航站看看. 先亮个像,我长这样: 导航站内容 区块链开发所涉及的资源: 如 项目白皮 ...

  8. ORA-01950:表空间“USERS”中无权限

    ORA-01950:表空间“USERS”中无权限 解决方案: A)确认给用户授权了resource角色 B)取消限制 ALTER USER "HCCPMS" QUOTA UNLIM ...

  9. react-native-syan-image-picker的使用

    传送门 第一种方式:link 第一步:安装 1.  npm install react-native-syan-image-picker --save 2.  react-native link re ...

  10. LDAP第三天 MySQL+LDAP 安装

    https://www.easysoft.com/applications/openldap/back-sql-odbc.html      OpenLDAP 使用 SQLServer 和 Oracl ...