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

条件

禁止在条件中使用常量表达式。

no-constant-condition

// ✗ bad
if (true) { /* ... */ }
while (x = -1) { /* ... */ }
let result = 0 ? a : b;

// ✓ good
if (x === 0) { /* ... */ }
while (x) { /* ... */ }
let result = x !== 0 ? a : b;

禁止在条件中出现赋值操作符,除非它们被括号包裹起来。

no-cond-assign

// ✗ bad
if (count = 0) { /* code */ }
while (node = node.parentNode) { /* code */ }

// ✓ good
if (count === 0) { /* code */ }
while ((node = node.parentNode)) { /* code */ }

禁止不必要的布尔类型转换。

no-extra-boolean-cast

// ✗ bad
let result = !!x ? a : b;
if (!!obj) {
    // ...
}
while (Boolean(obj)) {
    // ...
}

// ✓ good
let result = x ? a : b;
if (obj) {
    // ...
}
while (obj) {
    // ...
}

禁止不必要的三元表达式。

no-unneeded-ternary

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

尽量不使用否定表达式。

no-negated-condition

// ✗ bad
if (!condition)
    doSomething();
else
    doSomethingElse();

if (a !== b)
    doSomething();
else
    doSomethingElse();

// ✓ good
if (condition)
    doSomething();
else
    doSomethingElse();

if (a === b)
    doSomething();
else
    doSomethingElse();

禁止不安全的否定表达式。✎

no-unsafe-negation

// ✗ 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();

禁止用一个constlet声明多个变量,优先将const排列在let之前。

one-var

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

no-undef-init

// ✗ bad
let bar = undefined;

// ✓ good
let bar;
const baz = undefined;

禁止给const赋值,禁止重复声明。

no-const-assign, no-redeclare

// ✗ bad
const score = 100;
score = 125;
let name = 'John';
let name = 'Jane';

// ✓ good
let score = 100;
score = 125;
let name = 'John';
name = 'Jane';

禁止删除变量。

no-delete-var

delete只用于删除属性

// ✗ bad
let x;
delete x;

// ✓ good
delete obj.x;

禁止定义前使用。

no-use-before-define

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

尽量使用已经声明的变量。

no-unused-vars

// ✗ bad
function func() {
    let result = something();
}

命名

要求变量、对象和函数使用小驼峰命名。

camelcase

// ✗ bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}

// ✓ good
const thisIsMyObject = {};
function thisIsMyFunction() {}

要求构造器和类使用大驼峰命名。

new-cap

// ✗ 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 = [
  // ...
];

类型

禁止对StringNumberBooleanSymbolArrayObjectFunction使用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;

要求调用无参构造函数时有小括号。

new-parens

// ✗ bad
const date = new Date
const dog = new Animal;

// ✓ good
const date = new Date();
const dog = new Animal();

强制typeof表达式与有效的字符串进行比较。

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

尽量使用较短的符号实现类型转换。

no-implicit-coercion

// ✗ 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必须要有描述。

symbol-description

// ✗ bad
const foo = Symbol();

// ✓ good
const foo = Symbol('a symbol');

数字

要求书写完整的浮点小数。

no-floating-decimal

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

use-isnan

// ✗ bad
if (num === NaN) { /* ... */ }

// ✓ good
if (isNaN(num)) { /* ... */ }

禁止与-0比较,除非使用Object.is

no-compare-neg-zero

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

no-useless-return

// ✗ bad
function foo() { return; }
function foo() {
    doSomething();
    return;
}

// ✓ good
function foo() { return 5; }
function foo() {
    return doSomething();
}

要求使用内包型立即函数(IIFE)。✎

wrap-iife

// ✗ bad
function () {
    console.log('Hello');
}();
(function () {
    console.log('Hello');
}());

// ✓ good
(function () {
    console.log('Hello');
})();

禁止使用arguments,用...代替。

prefer-rest-params

// ✗ bad
function joinAll() {
    const args = Array.prototype.slice.call(arguments);
    return args.join('');
}

// ✓ good
function joinAll(...args) {
    return args.join('');
}

要求使用扩展运算符,而不是.apply()。✎

prefer-spread

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

no-useless-call

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

禁止使用callercallee

no-caller

arguments.callerarguments.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;
}

要求尽量使用箭头函数。

prefer-arrow-callback

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

要求箭头函数参数必须使用括号。

arrow-parens

// ✗ bad
[1, 2, 3].map(number => `A string containing the ${number}.`);

// ✓ good
[1, 2, 3].map((number) => `A string containing the ${number}.`);

要求尽量使用箭头函数的简写形式。

arrow-body-style

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

禁止不必要的函数绑定。

no-extra-bind

// ✗ 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单词。

consistent-this

// ✗ 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语句。

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

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

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