一份 ECMAScript 2015 的代码规范(下)

类和构造器

要求尽量使用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中添加不必要的构造函数。

no-useless-constructor

// ✗ 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;
    }
}

正则表达式

尽量不要在正则表达式字面量中出现多个空格。

no-regex-spaces

// ✗ bad
const reg = /abc   def/;

// ✓ good
const reg = /abc {3}def/;

禁止出现非法正则表达式。

no-invalid-regexp

// ✗ bad
RegExp('[a-z');

// ✓ good
RegExp('[a-z]');

禁止在正则表达式中出现空字符集。

no-empty-character-class

// ✗ bad
/^abc[]/.test('abcdefg');

// ✓ good
/^abc[a-z]/.test('abcdefg');

禁止在正则表达式中出现控制字符。

no-control-regex

// ✗ 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) {}

禁止对类进行赋值。

no-class-assign

// ✗ bad
class Dog {}
Dog = 'Fido';

禁止将全局对象当作函数进行调用。

no-obj-calls

// ✗ bad
let math = Math();
const json = JSON();

禁止出现重复的函数参数、对象属性、类成员方法、case标签以及imports。

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';

禁止未使用过的表达式。

no-unused-expressions

// ✗ 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

no-throw-literal

// ✗ bad
throw 'error';
throw 0;
throw undefined;
throw null;

// ✓ good
throw new Error();
throw new Error('error');
const e = new Error('error');
throw e;

禁止使用空解构模式。

no-empty-pattern

// ✗ 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;
}

要求注释的符号和内容之间有一个空格。✎

spaced-comment

// ✗ 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;
    }
}

生产环境

不推荐使用alertconfirmprompt

no-alert

// ✗ bad
alert('message');
confirm('Are you sure?');

在生产环境禁止出现console.logdebugger,允许出现console.infoconsole.warnconsole.error

no-console, no-debugger

// ✗ 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 的代码规范(上)

一份 ECMAScript 2015 的代码规范(中)

本文来自网易实践者社区,经作者赵雨森授权发布。