前端开发指南
1. 编码风格指南
建议写法
尾随逗号
多行写法的对象,建议在尾属性后面加上逗号。1
2
3
4
5
6
7// Example
var foo = {
bar: "baz",
qux: "quux",
};
var foo = {bar: "baz", qux: "quux"};
不使用 console.log
console.error 和 console.warn 通常用于函数中错误和警告的提示。1
2console.error('error');
console.warn('warn');
最佳实践
在类方法中使用 this
如果没有使用到 this,则该写到静态方法中。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class A {
foo() {
this.bar = "Hello World"; // OK, this is used
}
}
class A {
constructor() {
// OK. constructor is exempt
}
}
class A {
static foo() {
// OK. static methods aren't expected to use this.
}
}
不要使用 alert, confirm 和 prompt
应该使用更加友好的自定义 UI 交互。哪怕为此开发 UI 组件。通常 alert 用于开发调试,那么请在 production 版本将其移除。
不要在 else 块使用 return
如果 If 块包含返回语句,那么 else 块就没有必要了。它的内容可以放在外面的块。1
2
3
4
5
6function foo() {
if (x) {
return y;
}
return z;
}
不使用隐式转换
转换值类型的方法有很多,但是有一些可能不好读懂。例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14var b = !!foo;
var b = ~foo.indexOf(".");
var n = +foo;
var n = 1 * foo;
var s = "" + foo;
foo += ``;
// 建议
var b = Boolean(foo);
var b = foo.indexOf(".") !== -1;
var n = Number(foo);
var n = Number(foo);
var s = String(foo);
foo = String(foo);
不要在循环内放进函数
例如:1
2
3
4
5for (let results of data) {
_.each(results, function (value, key) {
// ......
});
}
储存 new 实例
例如:1
2
3
4var person = new Person();
// 不建议
new Person();
不要直接修改实参
直接修改实参,会使 arguments 对象发生变化,导致难以预料的错误。1
2
3
4
5
6
7function foo(bar) {
bar = 13;
}
function foo(bar) {
bar++;
}
不要使用 script url
例如:1
location.href = 'javascript: alert("hello")';
不要抛出错误字面值
直接抛出错误字面值,会丢失错误栈。正确写法如下:1
2
3
4
5
6
7
8
9
10
11
12throw new Error();
throw new Error("error");
var e = new Error("error");
throw e;
try {
throw new Error("error");
} catch (e) {
throw e;
}
在顶部声明变量
如果你使用的使 let 和 const,可以忽略这里。1
2
3
4
5
6
7
8
9
10
11
12function doSomething() {
var first;
var second; //multiple declarations are allowed at the top
if (true) {
first = true;
}
}
function doSomething() {
var i;
for (i=0; i<10; i++) {}
}
变量
不在局部作用域重复声明全局变量1
2
3
4
5
6
7
8
9
10
11
12var a = 3;
function b() {
var a = 10;
}
// 允许该情况,因为 if 块中的 a 事先声明了。
if (true) {
let a = 3;
let b = 6;
}
let a = 5;
不要留着没有被使用的变量
留着没有被使用过的变量,浪费内存,且不利于维护。
使用变量前需要先声明
不建议出现以下情况:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15alert(a);
var a = 10;
f();
function f() {}
function g() {
return b;
}
var b = 1;
{
alert(c);
let c = 1;
}
Node.js and CommonJS
按模块类型分组1
2
3
4
5
6
7
8
9
10
11
12
13
14// only require declarations (grouping off)
var eventEmitter = require('events').EventEmitter,
myUtils = require('./utils'),
util = require('util'),
bar = require(getBarModuleName());
// only non-require declarations
var foo = 42,
bar = 'baz';
// always valid regardless of grouping because all declarations are of the same type
var foo = require('foo' + VERSION),
bar = require(getBarModuleName()),
baz = require();
不使用合并路径
请使用 path module。因为不同系统类型可能导致无效路径。例如:1
2var fullPath = __dirname + "/foo.js";
var fullPath = __filename + "/foo.js";
编码风格
驼峰命名
命名变量的时候,camelcase 和 underscores 用在不同情况下:1
2
3
4
5
6
7
8
9
10// camelcase
var myFavoriteColor = "#112C85";
var _myFavoriteColor = "#112C85";
var myFavoriteColor_ = "#112C85";
var MY_FAVORITE_COLOR = "#112C85";
// underscores 用在对象属性
var obj = {
my_pref: 1
};
不使用匿名函数
那么你可以在堆栈里跟踪到函数表达式的名称。
缩进
tab 和 space 缩进都是允许的,但是同一个项目内建议保持一种风格。
我们建议使用 4 spaces。
大写字母开头的构造函数1
var friend = new Person();
不使用 continue
在循环中滥用 continue 会降低代码的可测试性。建议使用结构化的控制流语句,例如 if。
花括号之间不允许空格1
2
3
4
5
6
7
8
9
10
11
12var obj = {'foo': 'bar'};
var obj = {'foo': {'bar': 'baz'}, 'qux': 'quxx'};
var obj = {
'foo': 'bar'
};
var obj = {'foo': 'bar'
};
var obj = {
'foo':'bar'};
var obj = {};
var {x} = y;
import {foo} from 'bar';
其它建议
字符串模版
使用字符串模版连接字符串。1
2
3var str = "Hello World!";
var str = `Hello, ${name}!`;
var str = `Time: ${12 * 60 * 60 * 1000}`;
最长代码行
任何语言中非常长的代码行都很难读懂。为了提高可读性和可维护性,许多编码人员制定了一项约定,将代码行数限制在X个字符(传统上是80个字符)。
限制单文件代码行数
有些人认为大文件有代码味道。大型文件往往会做很多事情,并且很难跟上进度、难以维护。虽然现在并没有一个单文件最大行数的标准,但是不应该达到数千行。建议通常从100行到500行。
限制函数最多参数
函数的参数超过一定数量后,可能难以维护。你需要记住这个参数的意义、类型和顺序。因此我们建议当函数参数超过 3 个的时候,改为对象传入。
2. 代码注释规范
编写代码注释的必要性
代码注释能帮助阅读者更好地阅读和理解代码。
良好的代码注释,满足以下两个条件:
- 可阅读性,准确而简洁。
- 可维护性,易于修改,避免冗余。
注释类型
- 单行注释:通常放在代码块上方
- 文档类注释:API、类、函数(遵守 JSDOC 规范)
- 文件注释:文件头部书写固定格式的注释,注明作者、协议等信息
注释规范
单行注释1
2// 获取 App 对象
const APP = getApp()
多行注释
如果注释内容超过一行的时候,需要使用多行注释。多行注释请参考 JSDOC 规范。
1 | /** |
特殊标记
当你解决或者待解决一个缺陷,需要注释的时候。
1 | // @todo: 待完成某个功能 |
注释行上方空一行1
2
3
4
5// 注释1
const APP = getApp()
// 注释2
const PREFIX_URL = '...'
注释内容和注释符之间的空格1
2// 注释1
const APP = getApp()
3. 代码自释规范
代码自释说明
顾名思义:不需要注释,能够自解释的代码
优秀的代码有优秀的注释。而不友好的代码会给阅读和调试带来困扰,有可能误导后续的开发。因此我们除了提供优秀的注释,可以通过某些编程规范、技术让代码具备自解释的特征。
让代码具备做到自解释需要具备以下三个特征:
- 命名
- 语法
- 结构
命名
描述数值变量1
2const elementWidthPx =
window.getComputedStyle(element, null).getPropertyValue('width');
不使用 a 或者 b 描述变量,计数器除外。
遵循现有的命名规范。例如1
const element = getElement();
使用动词+对象构成来替代意义模糊的命名法:1
2
3
4
5// Bad
function handleFile(){};
// Good
function sendFile(){};
返回值:1
function getPropertyValue(){};
语法
使用更具语义的表达:1
2
3
4
5
6
7// Bad
isFunction && doit();
// Good
if (isFunction) {
doit();
}
使用大写字母+下划线组合的形式命名常量:1
2// 地球赤道周长
const EARTH_EQUATOR_LENGTH = 6378.2;
函数应用中减少使用命名模糊的参数:1
2
3
4
5// Bad
myThing.setData({ x: 1 }, true);
// Good
myThing.mergeData({ x: 1 });
使用语言自身提供的方法:1
2
3
4
5
6
7
8// Bad
let ids = [];
for(let i = 0; i < things.length; i++) {
ids.push(things[i].id);
}
// Good
let ids = things.map(thing => thing.id);
结构
适当的用函数名帮助解释:1
2
3
4var width = emToPixels(value);
function emToPixels(ems) {
return (ems - 0.5) * 16;
}
适当用变量帮助表达式解释:1
2
3
4var isVisible = el.offsetWidth && el.offsetHeight;
if(!isVisible) {
...
}
如果你认为别人难以明白你的数学表达式:1
2
3var multiplier = a * b;
var divisor = c / d;
return multiplier + divisor;
将具备相同功能,有紧密关系的代码分到一组:1
2
3
4
5
6var foo = 1;
bar(foo);
quux(foo);
blah()
xyz();
baz(1337);
4. 开发工具
本文使用 Visual Studio Code 配置 ESLint 实践 Javascript 编码规范。
可以使用其它 IDE 或者编辑器,而 .eslintrc 文件是通用的。
配置 VSCode + ESLint
安装 ESLint 扩展
打开 VSCode 面板并在扩展商店搜索 eslint ,通常是搜索结果列表的第一个。
| 名称 | 描述 | 作者 |
|---|---|---|
| ESLint | Integrates ESLint info VS Code | Drink Baeumer |
生成 .eslintrc.js 配置文件
首先全局安装:1
sudo npm i eslint -g
然后在硬盘上选择一个位置,执行以下命令,该命令会以询问的方式帮你配置并最后生成一个 .eslintrc.js|json|yaml 文件。1
eslint --init
覆盖 ESLint 配置
以 Mac OSX 为例,打开 Code-首选项-设置,编辑器会展开两列配置文件。分别是默认设置、用户设置。
默认设置是 VSCode 或者扩展提供的,如果需要修改,在用户设置用相同的键值对覆盖它。
请按下 command+F 打开搜索框,输入 eslint 并找到 "eslint.options":{},在用户设置添加1
2
3
4
5
6{
// 其它用户设置...
"eslint.options": {
"configFile": "[path].eslintrc.js" // .eslintrc.js 在硬盘上的路径
}
}
让 ESLint 检查 Vue 单文件组件
第一步全局安装 eslint-plugin-html,让 eslint 支持 Vue 单文件的代码检测。1
npm i eslint-plugin-html -g
然后打开编辑器的设置,在用户设置修改 eslint 的相关配置,如下:1
2
3
4
5
6
7
8
9"eslint.options": {
"configFile": "[path].eslintrc.js",
"plugins": ["html"]
},
"eslint.validate": [
"javascript",
"html",
"vue"
]