ES6中也要使用好严格的代码规范,助力你写出优雅的代码

2019-07-31 17:16:36 浏览数 (1)

常用约定

启用eslint

必需开启eslint检测, 且使用 standard规范检测,这样大家写出来的代码风格就可以保持一致

语法

类型规范

  • 对于常量或不修改的变量声明使用const,对于只在当前作用域下有效的变量,应使用let,不再使用var;
  • 优先使用const;
  • 将所有 const 变量放在一起,然后将所有 let 变量放在一起。
代码语言:javascript复制
const foo = 2222

let foo1 = 222222
let bar = foo
bar = 93333
foo1 = 33333
直接存取基本类型
  • 字符串
  • 数值
  • 布尔类型
  • null
  • undefined
代码语言:javascript复制
const foo = 1222;

let bar = foo;

bar = 9222222;

console.log(foo, bar);
通过引用的方式存取复杂类型,对所有的引用使用 const
  • 对象
  • 数组
  • 函数
代码语言:javascript复制
const foo = [1, 2, 3, 10];

const bar = foo;

bar[0] = 90000;
优先使用模板字符串,静态字符串一律使用单引号或反引号,不建议使用双引号。
代码语言:javascript复制
//bad
 const a = "foobar";
 const b = 'foo' a 'bb';

// good
const a = 'foobar';
const b = `foo${a}bar`;
使用字面量语法创建数组
代码语言:javascript复制
// bad
const items = new Array();

// good
const items = [];
使用字面值创建对象
代码语言:javascript复制
// bad

const item = new Object();

// good

const item = {};

解构规范

优先使用解构赋值
代码语言:javascript复制
const arr = [1, 2, 3, 4, 10];

// bad
const first = arr[0];
const second = arr[1];

// good
const [first, second] = arr;



// bad
function getFullName(user) {
  const firstName = user.firstName;
  const lastName = user.lastName;
}

// good
function getFullName(obj) {
  const { firstName, lastName } = obj;
}

// best
function getFullName({ firstName, lastName }) {
}



//如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。这样便于以后添加返回值,以及更改返回值的顺序。

// bad
function processInput(input) {
  return [left, right, top, bottom];
}

// good
function processInput(input) {
  return { left, right, top, bottom };
}

const { left, right } = processInput(input);
解构语句中统一不使用圆括号
代码语言:javascript复制
// bad
[(a)] = [11]; // a未定义
let { a: (b) } = {}; // 解析出错


// good
let [a, b] = [11, 22];
使用对象属性值的简写
代码语言:javascript复制
const aSkywalker = 'a Skywalker';

// bad

const obj = {

    aSkywalker: aSkywalker,

};

// good

const obj = {

    aSkywalker,

};
在对象属性声明前把简写的属性分组
代码语言:javascript复制
const a = 'Anakin Skywalker';

const b = 'a Skywalker';

// bad

const obj = {

    a: 1,

    b: 2,

    c: 3,

    d: 3,

    e: 4,

    z: 10,

};

// good

const obj = {

    a,

    b,

    c,

    d,

    e,

    f

};

函数

使用函数声明而不是函数表达式

函数声明拥有函数名,在调用栈中更加容易识别。并且,函数声明会整体提升,而函数表达式只会提升变量本身。这条规则也可以这样描述,始终使用箭头函数来代替函数表达式。

代码语言:javascript复制
// bad
const foo = function () {
};

// good
function foo() {
}
复制代码

绝对不要在一个非函数块(if,while,等等)里声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但是它们解析不同注:ECMA-262 把 块 定义为一组语句,函数声明不是一个语句。阅读 ECMA-262 对这个问题的说明

代码语言:javascript复制
// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

// good
if (currentUser) {
  var test = function test() {
    console.log('Yup.');
  };
}
复制代码

绝对不要把参数命名为 arguments, 这将会覆盖函数作用域内传过来的 arguments 对象

代码语言:javascript复制
// bad
function nope(name, options, arguments) {
  // ...stuff...
}

// good
function yup(name, options, args) {
  // ...stuff...
}
不要使用 arguments。可以选择 rest 语法 ... 替代。

使用 ... 能明确你要传入的参数。另外 rest 参数是一个真正的数组,而 arguments 是一个类数组。

代码语言:javascript复制
// bad

function concatenateAll() {

    const args = Array.prototype.slice.call(arguments);

    return args.join('');

}

// good

function concatenateAll(...args) {

    return args.join('');

}
复制代码
使用函数参数默认值语法,而不是修改函数的实参
代码语言:javascript复制
// really bad
function handleThings(opts) {
  opts = opts || {};
}

// still bad
function handleThings(opts) {
  if (opts === void 0) {
    opts = {};
  }
}

// good
function handleThings(opts = {}) {
  // ...
}
箭头函数

当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。

代码语言:javascript复制
// bad

[1, 2, 3].map(function (x) {

    return x * x;

});

// good

[1, 2, 3].map((x) => {

    return x * x;

});

如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。

代码语言:javascript复制
// good

[1, 2, 3].map(x => x * x);

// good

[1, 2, 3].reduce((total, n) => {

    return total   n;

}, 0);

总是使用 class 关键字,避免直接修改 prototype,class 语法更简洁,也更易理解。

代码语言:javascript复制
// 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;
  }
}
复制代码

定义类时,方法的顺序如下:

  • constructor
  • public get/set 公用访问器,set只能传一个参数
  • public methods 公用方法,公用相关命名使用小驼峰式写法(lowerCamelCase)
  • private get/set 私有访问器,私有相关命名应加上下划线 _ 为前缀
  • private methods 私有方法
代码语言:javascript复制
// good
class SomeClass {
  constructor() {
    // constructor
  }

  get aval() {
    // public getter
  }

  set aval(val) {
    // public setter
  }

  doSth() {
    // 公用方法
  }

  get _aval() {
    // private getter
  }

  set _aval() {
    // private setter
  }

  _doSth() {
    // 私有方法
  }
}
复制代码

如果不是class类,不使用new

代码语言:javascript复制
// not good
function Foo() {

}
const foo = new Foo();

// good
class Foo {

}
const foo = new Foo();
复制代码

使用 extends 关键字来继承

这是一个内置的继承方式,并且不会破坏 instanceof 原型检查。

代码语言:javascript复制
// 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];
    }
  }
复制代码

模块

总是在非标准的模块系统中使用标准的 import 和 export 语法,我们总是可以将标准的模块语法转换成支持特定模块加载器的语法。

推荐使用import和export来做模块加载

代码语言:javascript复制
// bad

const AirbnbStyleGuide = require('./AirbnbStyleGuide');

module.exports = AirbnbStyleGuide.es6;

// ok

import AirbnbStyleGuide from './AirbnbStyleGuide';

export default AirbnbStyleGuide.es6;

// best

import { es6 } from './AirbnbStyleGuide';

export default es6;

不要使用通配符 * 的 import,这样确保了一个模块只有一个默认的 export 项

代码语言:javascript复制
// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';

// good
import AirbnbStyleGuide from './AirbnbStyleGuide';

不要直接从一个 import 上 export

虽然一行代码看起来更简洁,但是有一个明确的 import 和一个明确的 export 使得代码行为更加明确。

代码语言:javascript复制
// bad
// filename es6.js
export default { es6 } from './airbnbStyleGuide';

// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;

多变量要导出时应采用对象解构形式

代码语言:javascript复制
// not good
export const a= 'a';
export const b= 'b';

// good
export const a= 'a';
export const b= 'b';

export default { a, b };

导出单一一个类时,确保你的文件名就是你的类名

代码语言:javascript复制
// file contents
class CheckB {
  // ...
}
module.exports = CheckB;

// in some other file
// bad
const checkB = require('./checkBox');

// bad
const checkB = require('./check_box');

// good
const checkB = require('./CheckB');

导出一个默认小驼峰命名的函数时,文件名应该就是导出的方法名

代码语言:javascript复制
function makeGuid() {
}

export default makeGuid;
复制代码

属性访问

使用点 . 操作符来访问常量属性

代码语言:javascript复制
const a = {
  b: true,
  age: 28
};

// bad
const b = a['b'];

// good
const b = a.b;

使用中括号[] 操作符来访问变量属性

代码语言:javascript复制
var a = {
  b: true,
  age: 28
};

function getProps(prop) {
  return a[prop];
}

var b = getProps('b');

0 人点赞