前端编程规范
一、背景
现代的Web应用比较复杂,很多情况下,需要团队成员一起合作完成,或者需要去维护其他成员的代码,所以编写可维护的代码就很重要。编写可维护代码的第一步就是认真考虑编码规范。遵守编码规范,可以提高代码可读性,减少bug可能性,使代码更易于理解,测试和维护。
对于前端来说涉及到的规范有HTML、CSS、JavaScript、TypeScript、VUE、React,相关内容比较细碎,本文主要分享一些重要的JavaScript相关规范。
二、参考规范
1. 书籍
《代码整洁之道》、《编写可维护的JavaScript》、《JavaScript高级程序设计第四版》
2. 文档
腾讯:tgideas.qq.com/doc/index.h…(比较老旧)
google:google.github.io/styleguide/…
airbnb:github.com/airbnb/java…、
Standard:standardjs.com/
3. 工具
Prettier:prettier.io/
Eslint:eslint.org/、zh-hans.eslint.org/
三、示例
以下主要分享命名和函数相关的内容。
关于命名
命名随处可见,比如给变量、函数、参数、类、库、目录、文件等命名。通用的一些命名规则如下:
1. 普通变量:小驼峰命名,名词(camelCase-首字母小写)
2. 函数:小驼峰命名,动词(camelCase-首字母小写)
3. 构造函数和类:大驼峰命名(PascalCase-第一个字母大写)
4. 常量:使用大写字符命名,并通过下划线分隔单词
5. 私有变量:一般用_单划线开头
6. 特殊命名:简称或缩写应全部大写或小写,如HTTP,URL
const studentCount = 10
function getData(){}
class Person{}
const MAX_COUNT= 10
const baseURL = '//xxx'
除了通用的命名规则外,命名还应该易读且有意义。有意义且易读的变量名,名称可以自解释,即增强代码可读性,又能减少注释;避免使用单字母或缩写。
// bad
let rcdDta = {}
// good
let recordData = {}
// bad
let c = 10
// good
let studentNumber = 10
关于函数
1. 函数应该短小
不要一个行数成百上千行,如果这样,可能包含太多功能,需要进行函数功能拆分或者进行函数优化。《代码整洁之道》中推荐不超过100行,20行封顶最佳。
2. 一个函数只做一件事
即函数的功能要单一,如果一个函数包含太多功能,会导致耦合,难以重构,测试,维护,理解等。要判断函数是否不止做了一件事,可以看能否从这个函数中再拆出一个函数。
// 反例
function submit() {
// 校验时间区间是否符合需求
// 校验参数是否满足需求
// 格式化参数
// 校验通过提交
}
// 正例
function submit() {
提交请求
}
3. 函数参数
函数参数尽量不超过两个,易传递,易理解,易测试。如果有很多参数就采用对象的形式,并且推荐对象解构。采用对象形式,易扩展;采用对象结构,很明确就能了解函数有哪些参数,还能浅克隆传递到函数中的参数,有助于防止副作用。
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`;
}
// good
function getFullName(user) {
const { firstName, lastName } = user;
return `${firstName} ${lastName}`;
}
// best
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
4. 函数名应该直接反映函数的作用
函数名常用动词或者动词+名词的形式。一些动词常见的约定:
can: 函数返回一个布尔值
has: 函数返回一个布尔值
is: 函数返回一个布尔值
get: 函数返回一个非布尔值
set: 函数用于保存一个值
// 真假 返回布尔值
function isObject() {}
function isVisible() {}
function hasName() {}
function hasPermission() {}
// 业务弹窗
function showAddModel() {}
function showEditModal() {}
// 改变状态
function changeUserStatus() {}
function changeUserPermission() {}
// 查询
function queryUserList() {}
function queryTableList() {}
function queryDetail() {}
// 页面增删改查
function handleAdd() {}
function handleDelete() {}
function handleEdit() {}
5. 别重复自己
重复的代码不仅会导致代码臃肿,而且不易维护和bug修复。如果发现自己在复制和粘贴代码,应该考虑将其重构为可重用的函数、模块或组件。
// bad
function addData() {
// doSomething
this.defaultData = {
a: '',
b: '',
c: ''
}
}
function updateData() {
// doSomething
this.defaultData = {
a: '',
b: '',
c: ''
}
}
// good
function initData () {
this.defaultData = {
a: '',
b: '',
c: ''
}
}
function addData() {
// doSomething
initData()
}
function updateData() {
// doSomething
initData()
}
6. 注意函数副作用
不要修改参数,不要对参数重新赋值。函数尽量是纯函数,返回结果只依赖它的参数,执行过程没有副作用。直接修改对象的属性或作为函数参数传递的数组的值可能会导致不良的副作用和难以跟踪的错误。可以考虑返回一个新对象或数组。
// bad
// 修改参数
function updateName (user) {
user.name = 'bob'
}
let user = { name: 'alice' }
updateName(user)
console.log(user) // { name: 'bob' }
// good
// 避免改变函数参数,而是返回新对象
function updateName (user) {
return { ...user, name: 'bob' }
}
let user = { name: 'alice' }
let updatedUser = updateName(user)
console.log(user) // { name: 'alice' }
console.log(updatedUser) // { name: 'bob' }
7. 更少的嵌套,尽早return,代码结构更加清晰分明。
// bad
function cats() {
if (x) {
return x;
} else if (y) {
return y;
}
}
// good
function foo() {
if (x) {
return x;
}
return y;
}
// good
function cats() {
if (x) {
return x;
}
if (y) {
return y;
}
}
除了命名和函数,还有格式化,注释等相关的规范。比如格式化涉及到的空格,缩进,要不要分号,行长度限制,什么时候换行,空行等;注释涉及到的单行注释,多行注释,什么时候添加注释,复杂代码注释等,这些有机会再分享。
参考文献
原文链接:https://juejin.cn/post/7343164002673786916 作者:liufeifeiholy