条件
禁止在条件中使用常量表达式。
// ✗ bad
if (true) { /* ... */ }
while (x = -1) { /* ... */ }
let result = 0 ? a : b;
// ✓ good
if (x === 0) { /* ... */ }
while (x) { /* ... */ }
let result = x !== 0 ? a : b;
禁止在条件中出现赋值操作符,除非它们被括号包裹起来。
// ✗ bad
if (count = 0) { /* code */ }
while (node = node.parentNode) { /* code */ }
// ✓ good
if (count === 0) { /* code */ }
while ((node = node.parentNode)) { /* code */ }
禁止不必要的布尔类型转换。
// ✗ bad
let result = !!x ? a : b;
if (!!obj) {
// ...
}
while (Boolean(obj)) {
// ...
}
// ✓ good
let result = x ? a : b;
if (obj) {
// ...
}
while (obj) {
// ...
}
禁止不必要的三元表达式。
// ✗ bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;
const bazz = num > 1 ? true : false;
// ✓ good
const foo = a || b;
const bar = !!c;
const baz = !c;
const bazz = num > 1;
禁止多行和嵌套的三元表达式。
no-nested-ternary, multiline-ternary
会使代码难以理解,请使用
if
语句。
// ✗ bad
let location = env.development
? 'localhost'
: 'www.api.com';
// ✓ good
let location = env.development ? 'localhost' : 'www.api.com';
// ✗ bad
let thing = foo ? bar : baz === qux ? quxx : foobar;
// ✓ good
let thing;
if (foo)
thing = bar;
else
thing = baz === qux ? quxx : foobar;
尽量不使用否定表达式。
// ✗ bad
if (!condition)
doSomething();
else
doSomethingElse();
if (a !== b)
doSomething();
else
doSomethingElse();
// ✓ good
if (condition)
doSomething();
else
doSomethingElse();
if (a === b)
doSomething();
else
doSomethingElse();
禁止不安全的否定表达式。✎
// ✗ bad
if (!key in obj) { /* code */ }
if (!obj instanceof Person) { /* code */ }
// ✓ good
if (!(key in obj)) { /* code */ }
if (!(obj instanceof Person)) { /* code */ }
if (('' + !key) in object) {/* code */ }
变量和作用域
要求声明变量优先使用const
,需要改变时使用let
,禁止使用var
或不声明变量。
no-undef, prefer-const, no-var
// ✗ bad
hero = new Hero();
var hero = new Hero();
// ✓ good
const hero = new Hero();
禁止用一个const
或let
声明多个变量,优先将const
排列在let
之前。
// ✗ bad
const bar = true,
num = 20,
items = getItems();
let index = 0,
silent = false,
hero = new Hero();
// ✗ bad
const bar = true;
let silent = false;
let index = 0;
const num = 20;
const items = getItems();
let hero = new Hero();
// ✓ good
const bar = true;
const num = 20;
const items = getItems();
let index = 0;
let silent = false;
let hero = new Hero();
禁止初始化变量值为undefined
。✎
// ✗ bad
let bar = undefined;
// ✓ good
let bar;
const baz = undefined;
禁止给const
赋值,禁止重复声明。
// ✗ bad
const score = 100;
score = 125;
let name = 'John';
let name = 'Jane';
// ✓ good
let score = 100;
score = 125;
let name = 'John';
name = 'Jane';
禁止删除变量。
delete
只用于删除属性
// ✗ bad
let x;
delete x;
// ✓ good
delete obj.x;
禁止定义前使用。
// ✗ bad
alert(a);
const a = 10;
f();
function f() {}
function g() {
return b;
}
const b = 1;
// ✓ good
const a = 10;
alert(a);
function f() {}
f(1);
const b = 1;
function g() {
return b;
}
尽量使用已经声明的变量。
// ✗ bad
function func() {
let result = something();
}
命名
要求变量、对象和函数使用小驼峰命名。
// ✗ bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
// ✓ good
const thisIsMyObject = {};
function thisIsMyFunction() {}
要求构造器和类使用大驼峰命名。
// ✗ bad
function user(options) {
this.name = options.name;
}
const bad = new user({
name: 'nope',
});
// ✓ good
class User {
constructor(options) {
this.name = options.name;
}
}
const good = new User({
name: 'yup',
});
要求首个缩写单词中的每个字母具有相同的大小写形式。
命名是为了可读性,而不是为了机械地去贴近一个算法。
// ✗ bad
import SmsContainer from './containers/SmsContainer';
// ✗ bad
const HttpRequests = [
// ...
];
// ✓ good
import SMSContainer from './containers/SMSContainer';
// ✓ good
const HTTPRequests = [
// ...
];
类型
禁止对String
、Number
、Boolean
、Symbol
、Array
、Object
、Function
使用new操作符。
no-new-wrappers, no-new-symbol, no-array-constructor, no-new-object, no-new-func
// ✗ bad
const str = new String('Hello world');
const num = new Number(33);
const bool = new Boolean(false);
const sym = new Symbol('sym');
const arr = new Array();
const obj = new Object();
const func = new Function('a', 'b', 'return a + b');
// ✓ good
const str = String(value);
const num = Number(value);
const bool = Boolean(value);
const sym = Symbol('sym');
const arr = [];
const obj = {};
const func = (a, b) => a + b;
要求调用无参构造函数时有小括号。
// ✗ bad
const date = new Date
const dog = new Animal;
// ✓ good
const date = new Date();
const dog = new Animal();
强制typeof
表达式与有效的字符串进行比较。
// ✗ bad
typeof x === 'strnig';
typeof x === 'undefimed';
typeof x === 'nunber';
typeof x === 'fucntion';
// ✓ good
typeof x === 'string';
typeof x === 'undefined';
typeof x === type;
typeof x === typeof y;
尽量使用较短的符号实现类型转换。
// ✗ bad
let b = Boolean(foo);
let b = foo.indexOf('.') !== -1;
let n = Number(foo);
let s = String(foo);
foo = String(foo);
// ✓ good
let b = !!foo;
let b = ~foo.indexOf('.');
let n = +foo;
let s = '' + foo;
foo += '';
要求Symbol
必须要有描述。
// ✗ bad
const foo = Symbol();
// ✓ good
const foo = Symbol('a symbol');
数字
要求书写完整的浮点小数。
// ✗ bad
let num = .5;
let num = 2.;
let num = -.7;
// ✓ good
let num = 0.5;
let num = 2.0;
let num = -0.7;
要求调用isNaN()
检查NaN
。
// ✗ bad
if (num === NaN) { /* ... */ }
// ✓ good
if (isNaN(num)) { /* ... */ }
禁止与-0
比较,除非使用Object.is
。
// ✗ bad
if (x === -0) { /* ... */ }
// ✓ good
if (x === 0) { /* ... */ }
if (Object.is(x, -0)) { /* ... */ }
函数和箭头函数
要求使用函数表达式,而不是函数声明。
func-style, no-inner-declarations, no-func-assign
函数声明很容易被提升到当前作用域的顶部,这意味着可以把调用它的语句放在函数声明之前。
// ✗ bad
function foo() {
// ...
}
// ✓ good
const foo = function () {
// ...
}
const foo = () => { /* ... */ }
禁止不必要的return
。
// ✗ bad
function foo() { return; }
function foo() {
doSomething();
return;
}
// ✓ good
function foo() { return 5; }
function foo() {
return doSomething();
}
要求使用内包型立即函数(IIFE)。✎
// ✗ bad
function () {
console.log('Hello');
}();
(function () {
console.log('Hello');
}());
// ✓ good
(function () {
console.log('Hello');
})();
禁止使用arguments
,用...
代替。
// ✗ bad
function joinAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// ✓ good
function joinAll(...args) {
return args.join('');
}
要求使用扩展运算符,而不是.apply()
。✎
// ✗ bad
const x = [1, 2, 3, 4, 5];
console.log.apply(console, x);
// ✓ good
const x = [1, 2, 3, 4, 5];
console.log(...x);
// ✗ bad
new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
// ✓ good
new Date(...[2016, 8, 5]);
禁用不必要的.call()
和.apply()
。
// ✗ bad
// These are same as `foo(1, 2, 3);`
foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
foo.call(null, 1, 2, 3);
foo.apply(null, [1, 2, 3]);
// These are same as `obj.foo(1, 2, 3);`
obj.foo.call(obj, 1, 2, 3);
obj.foo.apply(obj, [1, 2, 3]);
// ✓ good
foo(1, 2, 3);
obj.foo(1, 2, 3):
尽量使用默认值参数语法,而不是手动设置默认值。并且尽量将默认值参数放在最后。
// ✗ bad
function handle(options) {
options = options || {};
// ...
}
// ✓ good
function handle(options = {}) {
// ...
}
// ✗ bad
function handle(options = {}, name) {
// ...
}
// ✓ good
function handle(name, options = {}) {
// ...
}
禁止使用caller
或callee
。
arguments.caller
和arguments.callee
,在JavaScript的新版本中它们已被弃用,同时在 ECMAScript 5的严格模式下,它们也是被禁用的。
// ✗ bad
function factorial(n) {
return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
}
// ✓ good
function factorial(n) {
return !(n > 1) ? 1 : factorial(n - 1) * n;
}
要求尽量使用箭头函数。
// ✗ bad
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
// ✓ good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
要求箭头函数参数必须使用括号。
// ✗ bad
[1, 2, 3].map(number => `A string containing the ${number}.`);
// ✓ good
[1, 2, 3].map((number) => `A string containing the ${number}.`);
要求尽量使用箭头函数的简写形式。
// ✗ bad
[1, 2, 3].map((number) => {
const nextNumber = number + 1;
`A string containing the ${nextNumber}.`;
});
// ✓ good
[1, 2, 3].map(number => `A string containing the ${number}.`);
禁止不必要的函数绑定。
// ✗ bad
const x = function () {
foo();
}.bind(bar);
const x = (() => {
foo();
}).bind(bar);
const x = (() => {
this.foo();
}).bind(bar);
const x = function () {
(function () {
this.foo();
}());
}.bind(bar);
const x = function () {
function foo() {
this.bar();
}
}.bind(baz);
// ✓ good
const x = function () {
this.foo();
}.bind(bar);
const x = function (a) {
return a + 1;
}.bind(foo, bar);
如果要引用this
,要求统一使用self
单词。
// ✗ bad
function foo() {
const that = this;
return function () {
console.log(that);
};
}
// ✓ good
function foo() {
const self = this;
return function () {
console.log(self);
};
}
// ✓ best
function foo() {
return () => console.log(self);
}
要求数组方法的回调函数中有return
语句。
该规则发现以下方法的回调函数,然后检查return语句的使用。
Array.from
Array.prototype.every
Array.prototype.filter
Array.prototype.find
Array.prototype.findIndex
Array.prototype.map
Array.prototype.reduce
Array.prototype.reduceRight
Array.prototype.some
Array.prototype.sort
// ✓ good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
// ✓ good
[1, 2, 3].map((x) => x + 1);
// ✗ bad
const flat = {};
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item);
flat[index] = flatten;
});
// ✓ good
const flat = {};
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item);
flat[index] = flatten;
return flatten;
});
// ✗ bad
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird')
return author === 'Harper Lee';
else
return false;
});
// ✓ good
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird')
return author === 'Harper Lee';
return false;
});
相关阅读:一份 ECMAScript 2015 的代码规范(上)
本文来自网易云社区,经作者赵雨森授权发布。