// ✗ 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();
}
// ✗ 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 的代码规范(上)
本文来自网易实践者社区,经作者赵雨森授权发布。