常用约定
启用eslint
必需开启eslint检测, 且使用 standard规范检测,这样大家写出来的代码风格就可以保持一致
语法
类型规范
- 对于常量或不修改的变量声明使用const,对于只在当前作用域下有效的变量,应使用let,不再使用var;
- 优先使用const;
- 将所有 const 变量放在一起,然后将所有 let 变量放在一起。
const foo = 2222
let foo1 = 222222
let bar = foo
bar = 93333
foo1 = 33333
直接存取基本类型
- 字符串
- 数值
- 布尔类型
- null
- undefined
const foo = 1222;
let bar = foo;
bar = 9222222;
console.log(foo, bar);
通过引用的方式存取复杂类型,对所有的引用使用 const
- 对象
- 数组
- 函数
const foo = [1, 2, 3, 10];
const bar = foo;
bar[0] = 90000;
优先使用模板字符串,静态字符串一律使用单引号或反引号,不建议使用双引号。
代码语言:javascript复制//bad
const a = "foobar";
const b = 'foo' a 'bb';
// good
const a = 'foobar';
const b = `foo${a}bar`;
使用字面量语法创建数组
代码语言:javascript复制// bad
const items = new Array();
// good
const items = [];
使用字面值创建对象
代码语言:javascript复制// bad
const item = new Object();
// good
const item = {};
解构规范
优先使用解构赋值
代码语言:javascript复制const arr = [1, 2, 3, 4, 10];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
}
// good
function getFullName(obj) {
const { firstName, lastName } = obj;
}
// best
function getFullName({ firstName, lastName }) {
}
//如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。这样便于以后添加返回值,以及更改返回值的顺序。
// bad
function processInput(input) {
return [left, right, top, bottom];
}
// good
function processInput(input) {
return { left, right, top, bottom };
}
const { left, right } = processInput(input);
解构语句中统一不使用圆括号
代码语言:javascript复制// bad
[(a)] = [11]; // a未定义
let { a: (b) } = {}; // 解析出错
// good
let [a, b] = [11, 22];
使用对象属性值的简写
代码语言:javascript复制const aSkywalker = 'a Skywalker';
// bad
const obj = {
aSkywalker: aSkywalker,
};
// good
const obj = {
aSkywalker,
};
在对象属性声明前把简写的属性分组
代码语言:javascript复制const a = 'Anakin Skywalker';
const b = 'a Skywalker';
// bad
const obj = {
a: 1,
b: 2,
c: 3,
d: 3,
e: 4,
z: 10,
};
// good
const obj = {
a,
b,
c,
d,
e,
f
};
函数
使用函数声明而不是函数表达式
函数声明拥有函数名,在调用栈中更加容易识别。并且,函数声明会整体提升,而函数表达式只会提升变量本身。这条规则也可以这样描述,始终使用箭头函数来代替函数表达式。
代码语言:javascript复制// bad
const foo = function () {
};
// good
function foo() {
}
复制代码
绝对不要在一个非函数块(if,while,等等)里声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但是它们解析不同注:ECMA-262 把 块 定义为一组语句,函数声明不是一个语句。阅读 ECMA-262 对这个问题的说明
代码语言:javascript复制// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
if (currentUser) {
var test = function test() {
console.log('Yup.');
};
}
复制代码
绝对不要把参数命名为 arguments, 这将会覆盖函数作用域内传过来的 arguments 对象
代码语言:javascript复制// bad
function nope(name, options, arguments) {
// ...stuff...
}
// good
function yup(name, options, args) {
// ...stuff...
}
不要使用 arguments。可以选择 rest 语法 ... 替代。
使用 ... 能明确你要传入的参数。另外 rest 参数是一个真正的数组,而 arguments 是一个类数组。
代码语言:javascript复制// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
复制代码
使用函数参数默认值语法,而不是修改函数的实参
代码语言:javascript复制// really bad
function handleThings(opts) {
opts = opts || {};
}
// still bad
function handleThings(opts) {
if (opts === void 0) {
opts = {};
}
}
// good
function handleThings(opts = {}) {
// ...
}
箭头函数
当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
代码语言:javascript复制// bad
[1, 2, 3].map(function (x) {
return x * x;
});
// good
[1, 2, 3].map((x) => {
return x * x;
});
如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。
代码语言:javascript复制// good
[1, 2, 3].map(x => x * x);
// good
[1, 2, 3].reduce((total, n) => {
return total n;
}, 0);
类
总是使用 class 关键字,避免直接修改 prototype,class 语法更简洁,也更易理解。
代码语言:javascript复制// bad
function Queue(contents = []) {
this._queue = [...contents];
}
Queue.prototype.pop = function() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []) {
this._queue = [...contents];
}
pop() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
复制代码
定义类时,方法的顺序如下:
- constructor
- public get/set 公用访问器,set只能传一个参数
- public methods 公用方法,公用相关命名使用小驼峰式写法(lowerCamelCase)
- private get/set 私有访问器,私有相关命名应加上下划线 _ 为前缀
- private methods 私有方法
// good
class SomeClass {
constructor() {
// constructor
}
get aval() {
// public getter
}
set aval(val) {
// public setter
}
doSth() {
// 公用方法
}
get _aval() {
// private getter
}
set _aval() {
// private setter
}
_doSth() {
// 私有方法
}
}
复制代码
如果不是class类,不使用new
代码语言:javascript复制// not good
function Foo() {
}
const foo = new Foo();
// good
class Foo {
}
const foo = new Foo();
复制代码
使用 extends 关键字来继承
这是一个内置的继承方式,并且不会破坏 instanceof 原型检查。
代码语言:javascript复制// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
复制代码
模块
总是在非标准的模块系统中使用标准的 import 和 export 语法,我们总是可以将标准的模块语法转换成支持特定模块加载器的语法。
推荐使用import和export来做模块加载
代码语言:javascript复制// bad
const AirbnbStyleGuide = require('./AirbnbStyleGuide');
module.exports = AirbnbStyleGuide.es6;
// ok
import AirbnbStyleGuide from './AirbnbStyleGuide';
export default AirbnbStyleGuide.es6;
// best
import { es6 } from './AirbnbStyleGuide';
export default es6;
不要使用通配符 * 的 import,这样确保了一个模块只有一个默认的 export 项
代码语言:javascript复制// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';
// good
import AirbnbStyleGuide from './AirbnbStyleGuide';
不要直接从一个 import 上 export
虽然一行代码看起来更简洁,但是有一个明确的 import 和一个明确的 export 使得代码行为更加明确。
代码语言:javascript复制// bad
// filename es6.js
export default { es6 } from './airbnbStyleGuide';
// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
多变量要导出时应采用对象解构形式
代码语言:javascript复制// not good
export const a= 'a';
export const b= 'b';
// good
export const a= 'a';
export const b= 'b';
export default { a, b };
导出单一一个类时,确保你的文件名就是你的类名
代码语言:javascript复制// file contents
class CheckB {
// ...
}
module.exports = CheckB;
// in some other file
// bad
const checkB = require('./checkBox');
// bad
const checkB = require('./check_box');
// good
const checkB = require('./CheckB');
导出一个默认小驼峰命名的函数时,文件名应该就是导出的方法名
代码语言:javascript复制function makeGuid() {
}
export default makeGuid;
复制代码
属性访问
使用点 . 操作符来访问常量属性
代码语言:javascript复制const a = {
b: true,
age: 28
};
// bad
const b = a['b'];
// good
const b = a.b;
使用中括号[] 操作符来访问变量属性
代码语言:javascript复制var a = {
b: true,
age: 28
};
function getProps(prop) {
return a[prop];
}
var b = getProps('b');