class
,避免手动操作prototype
。
// ✗ 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;
}
}
extends
做继承。
// ✗ 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];
}
}
class
中添加不必要的构造函数。
// ✗ bad
class Jedi {
constructor() {}
getName() {
return this.name;
}
}
// ✗ bad
class Rey extends Jedi {
constructor(...args) {
super(...args);
}
}
// ✓ good
class Rey extends Jedi {
constructor(...args) {
super(...args);
this.name = 'Rey';
}
}
super()
调用,禁止在调用super()
之前使用this
。
constructor-super, no-this-before-super
// ✗ bad
class Dog extends Animal {
constructor () {
this.legs = 4;
}
}
// ✗ bad
class Dog extends Animal {
constructor () {
this.legs = 4;
super();
}
}
// ✓ good
class Dog extends Animal {
constructor () {
super();
this.legs = 4;
}
}
// ✗ bad
const reg = /abc def/;
// ✓ good
const reg = /abc {3}def/;
// ✗ bad
RegExp('[a-z');
// ✓ good
RegExp('[a-z]');
// ✗ bad
/^abc[]/.test('abcdefg');
// ✓ good
/^abc[a-z]/.test('abcdefg');
// ✗ bad
const pattern = /\x1f/;
// ✓ good
const pattern = /\x20/;
no-self-assign, no-self-compare
// ✗ bad
foo = foo;
[a, b] = [a, b];
// ✗ bad
let x = 10;
if (x === x)
x = 20;
no-global-assign, no-shadow-restricted-names
// ✗ bad
Object = null;
undefined = 1;
window = {};
function NaN() {}
try {} catch(eval) {}
// ✗ bad
class Dog {}
Dog = 'Fido';
// ✗ bad
let math = Math();
const json = JSON();
no-dupe-args, no-dupe-keys, no-dupe-class-members, no-duplicate-case, no-duplicate-imports
// ✗ bad
function foo(a, b, a) {
console.log(a, b);
}
// ✗ bad
const obj = {
name: 'alice',
name: 'bob',
'name': 'carol',
};
// ✗ bad
class Dog {
bark () {}
bark () {}
}
// ✗ bad
switch (id) {
case 1:
// ...
case 1:
}
// ✗ bad
import { myFunc1 } from 'module';
import { myFunc2 } from 'module';
// ✗ bad
0
if(0) 0
{0}
f(0), {}
(function anIncompleteIIFE () {});
a && b
a ? b : 0
// ✓ good
a = 0
new C()
delete a.b
void a
a && b()
a ? b() : c()
eval
以及类似eval
的方法。
eval, no-implied-eval, no-script-url
// ✗ bad
let value = eval('obj.' + key);
setTimeout('alert("Hi!");', 100);
setInterval('alert("Hi!");', 100);
execScript('alert("Hi!")');
location.href = 'javascript:void(0)';
// ✓ good
let value = obj[key];
setTimeout(function() {
alert('Hi!');
}, 100);
setInterval(function() {
alert('Hi!');
}, 100);
alert('Hi!');
void
, with
, label
, __iterator__
, __proto__
no-void, no-with, no-labels, no-unused-labels, no-extra-label, no-label-var, no-iterator, [no-proto]
Error
。
// ✗ bad
throw 'error';
throw 0;
throw undefined;
throw null;
// ✓ good
throw new Error();
throw new Error('error');
const e = new Error('error');
throw e;
// ✗ bad
const {} = foo;
const [] = foo;
const {a: {}} = foo;
const {a: []} = foo;
function foo({}) {}
function foo([]) {}
function foo({a: {}}) {}
function foo({a: []}) {}
// ✓ good
const {a = {}} = foo;
const {a = []} = foo;
function foo({a = {}}) {}
function foo({a = []}) {}
/** ... */
。
// ✗ bad
// make() returns a new element
// based on the passed in tag name
//
// @param {String} tag
// @return {Element} element
function make(tag) {
// ...
return element;
}
// ✓ good
/**
* make() returns a new element
* based on the passed-in tag name
* @param {String} tag
* @return {Element} element
*/
function make(tag) {
// ...
return element;
}
//
,尽量将单行注释放在代码上方,要求在单行注释前放一个空行,除非它是块中的首行。
// ✗ bad
const active = true; // is current tab
// ✓ good
// is current tab
const active = true;
// ✗ bad
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
const type = this.type || 'no type';
return type;
}
// ✓ good
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
const type = this.type || 'no type';
return type;
}
// ✓ good
function getType() {
// set the default type to 'no type'
const type = this.type || 'no type';
return type;
}
// ✗ bad
//is current tab
const active = true;
// ✓ good
// is current tab
const active = true;
// ✗ bad
/**
*make() returns a new element
*based on the passed-in tag name
*/
function make(tag) {
// ...
return element;
}
// ✓ good
/**
* make() returns a new element
* based on the passed-in tag name
*/
function make(tag) {
// ...
return element;
}
FIXME
标注一个问题,使用TODO
标注一个计划。// ✓ good
class Calculator extends Abacus {
constructor() {
super();
// FIXME: shouldn't use a global here
total = 0;
}
}
class Calculator extends Abacus {
constructor() {
super();
// TODO: total should be configurable by an options param
this.total = 0;
}
}
alert
、confirm
、prompt
。
// ✗ bad
alert('message');
confirm('Are you sure?');
console.log
和debugger
,允许出现console.info
、console.warn
和console.error
。
// ✗ bad
console.log('code info.');
debugger;
// ✓ good
console.info('Running in development mode.');
console.warn('This method is deprecated.');
console.error('Circular dependencies!')
相关阅读:一份 ECMAScript 2015 的代码规范(上)
本文来自网易实践者社区,经作者赵雨森授权发布。