es6规范

926 阅读3分钟

引用

对所有变量使用const代替var, 如果一定要改变引用值,使用let代替var

// bad
var a = 1;

// good
const b = 1;

// bad
var flag = 0;
if (cond) {
  flag = 0
}

// good 
let flag = 1;
if (cond) {
  flag = 0;
}

对象

创建字面量

// bad
const item = new Object();

// good
const item = {}

创建带计算的属性名

const getKey = (v) => `key${v}`;

// bad
const obj = {
  id: 1,
};
obj[getKey(1)] = "wuw";

// good
const obj = {
  id: 2,
  [getKey(2)] = "polm",
};

速记语法

// bad
const name = "wuw";
const obj = {
  name: name,
};

// good
const obj = {
  name
}


// bad
const obj1 = {
  name: "wuw",
  getName: (v) => obj1.name,
};

// good
const obj1 = {
  name: "wuw",
  getName() {
    return obj1.name;
  },
};

引号使用,会改变语法高亮

// bad
const obj = {
  "id": 1,
  "name": "wuw",
  "data-test": "haha"
}

// good
const obj = {
  id: 1,
  name: "wuw",
  "data-test": "haha"
}

使用...优先于Object.assign

// very bad
const obj = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 });
delete copy.a;

// good
const obj = { a: 1, b: 2 };
const copy = { ...obj, c: 3 };

const { a, ...noA } = copy;

数组

数组创建

// bad
const arr = new Array();

// good
const arr = [];

数组复制

// bad
const copy = [];
for (let i = 0; const len = item.length; i < len; i++) {
  copy[i] = item[i];
}

// good
const copy = [...item];

数组添加元素

const a = [];

// bad
a[a.length] = 1;

// good
a.push(1);

类数组转换

const set = new Set();

// good
const arr = Array.from(set);

// best
const arr = [...set];

解构

对象解构

// bad
function getFullName(user) {
  const firstName = user.firstName;
  const lastName = user.lastName;
 
  return `${firstName} ${lastName}`;
}
 
// good
function getFullName(user) {
  const { firstName, lastName } = user;
  return `${firstName} ${lastName}`;
}
 
// best
function getFullName({ firstName, lastName }) {
  return `${firstName} ${lastName}`;
}

数组解构

const arr = [1, 2, 3];

// bad
const a = arr[0];
const b = arr[1];

// good
const [a, b] = arr;

出入参

  • 入参超过3个时,使用对象代替元素, 可以不用考虑顺序
// bad
function func(a1, a2, a3, a4) {
  
}

// good
function func({ a1, ...res}) {
  
}
  • 出参超过3个,使用对象代替数组, 可以不用考虑顺序
function func() {
  return [a1, a2, a3, a4];
}

// good
function func() {
  return { a1, a2, a3, a4 };
}

字符串

// bad - 模板字符串应该包含变量
const str = `aaa`;

// good
const str = "aaa"

// bad
const name = "wuw";
const str1 = ["hi", name, '~'].join();

// bad
const name = "wuw";
const str1 = "hi" + name + "~";

// bad
const name = "wuw";
const str1 = `hi ${ name } ~`;

// good
const name = "wuw";
const str1 = `hi ${name} ~`;

函数

使用命名函数代替函数声明

  • 函数声明会被变量提升
  • 可读性和可维护性造成影响
// bad
function func1() {
  
}

// good
const func1 = () => {
  
}

不在非函数代码块中进行函数声明

// bad
if (cond) {
  function fun() {
    
  }
}

// good 
let func;
if (cond) {
  func = () => {
    
  }
}

函数参数不要使用arguments, 会覆盖原有作用域的arguments, 使用...代替

// very bad
function (a1, arguments) {
  
}

// good
function (a1, ...args) {
  
}

函数默认值

// bad - 会改变对象false值
function func(opts) {
  opts = opts || {};
}
func(0)  // {}
func(NaN)  // {}
func(null)  // {}
func(undefine)  // {}


// good
function func(opts = {}) {
  
}

func(0)  // 0
func(NaN)  // NaN
func(null)  // null
func(undefine)  // {}

将有默认值的参数放在最后

箭头函数

// bad
[1, 2].map((v) => v + 1);

// good
[1, 2].map(v => v + 1);
[1, 2].map(v => (
  `llllllllllllllllllllllllllllllllllll${v}onggggggggggggggggggg`
))
[1, 2].map(v => {
  const u = v + 1;
  return u * v;
})

构造函数

避免空的构造函数

// bad
constructor(...args) {
  super(...args);
}

// good
constructor(...args) {
  super(...args);
  this.name = "wuw";
}

模块

// bad
const module1 = require('./Module');
model.exports = module1.test;

// good
import module1 from './Module';
expoer default module1.test;

// best
import { test } from './Module';
export default test;

相同路径导入

// bad
import foo from 'foo';
import { bar } from 'foo';

// good
import foo, { bar } from 'foo';

导出 - 尽量使用一个导出利于维护

// bad
export function fun() {}

// ok
const func = () => {}
export {
  func
}

// good
export default function foo() {}

import位于所有非导入语句上面

import会被提升, 防止出错

// bad
import foo from 'foo';
const COUNT = 10;
import bar form 'bar';

// good
import foo from 'foo';
import bar form 'bar';

const COUNT = 10;

迭代器

使用高阶函数代替迭代器,避免for-infor-of循环的使用

  • 纯函数,容易维护
  • map() every() filter() find() findIndex() reducer() some()
  • Object.key() Object.values() Object.entries() 对象生成迭代数组
// bad
let sum = 0;
for (let num of numbers) {
    sum += num;
}

for (let i = 0, const len = numbers.length; i < len; i++) { 
  arr.push(numbers[i] + 1); 
}

// good
numbers.forEach((num) => {
    sum += num;
});

numbers.forEach((num) => {
  arr.push(num + 1);
});


// best
const sum = numbers.reduce((total, num) => total + num, 0);
const arr = numbers.map(num => num + 1);

代码风格

操作符

/* -- 判断 - start -- */
// bad
flag == true; // === 代替 === 
const ans = (a > 1 || b > 2 || check()) ? doSomeThing() : doOther()

// good
const a == 1;
const ans = (a > 1 || b > 2 || check()) 
              ? doSomeThing() 
              : doOther();

flag === true;
/* -- 判断 - end -- */


/* -- 长判断 - start -- */
// bad - 长判断
if ((a >= 2 && b < 3) || checkSomething() || (number + getValue() === 6)) {} 

// good
if (
  (a >= 2 && b < 3)
  && checkSomething()
  && (number + getValue() === 6)
) {}

/* -- 长判断 - end -- */


/* -- 混合操作符使用括号 - start -- */
// bad
const foo = a && b < 0 || c > 0 || d + 1 === 0; // 
const ans = a * 3 - b / 2;

// good
const foo = (a && b < 0) || c > 0 || (d + 1 === 0);
const ans = (a * 3) - (b / 2);
/* -- 混合操作符使用括号 - end -- */

空格

使用两个空格作为缩进


// bad - 运算符左右两边加空格
const a=1;
const a= 1;
const b = a+1;
const obj = {a:1}; // 大括号左右两边空格 :右侧空格
if ( cond ) {} // 小括号左右两边不加空格

const ans = a?1:0;

function func(){};
function func () {};
const func=() => {};

const a = 1;?  // 行末尾不加空格

if() {}
if (){}

class Dog{
  getName(){
    
  }
}

switch (cond) {
    
}

import {a} from 'sss';

// good
const a = 1;
const b = a + 1;
const obj = { a: 1 };
if (cond) {}

const a = a ? 1 : 0;

function func() {};
const func = () => {};

if () {}

class Dog {
  getName() { // 左侧无空格
    
  }
}

switch(cond) {
    
}

import { a } from 'sss';

空行

  • 不同逻辑代码段之间需要空行
  • 文件结尾加空行
  • 不要用空白行填充代码段
const isEated = checkEated();
if (isEated) {
  
}

doAnother();

doLasteThing();

// bad
function func() {
  
  console.log('kkk')
  
}

// good
function func() {
  console.log('kkk')
}

变量

// bad
const a = 1,  // 容易出现, ;错乱
      b = 2,
      c = 3;

const a = 1;
let flag = true;
const b = 2;

// good
const a = 1;
const b = 2;
const c = 3;

const a = 1;
const b = 2;
let flag = true;

代码块

// bad
if (cond)
  return;

if (cond) { return false; }

if (cond) { //不一换行
  
} 
else {
  
}

function func() {
  if (cond) {
    return x;
  } else {
    return y;  // 不需要else
  }
}

switch(cond) {
  case 1:
    // 不加break需要额外写注释
  case 2:
    doSomething();
    break;
  // default不能缺少
}

// good
if (cond) return;  // 除直接return 都需要加{} 并换行
if (cond) {
  return false;
}

if (cond) {

} else {
  
}

function func() {
  if (cond) {
    return x;
  } 
  
  return y;
}

switch(cond) {
  case 1:
    check();
    break;
  case 2:
    doSomething();
    break;
  defalut:
    // 为空需要写注释
}

链式调用

// bad
const ans = getValue().fist().second().third() 两个以上换行以.开头

// good
const ans = getValue()
  .fist()
  .second()
  .third()

简写代码

// bad
const a = check() ? doSomething() : null;
let flag = 1;
if (cond) {
  flag = 0;
}

// good
const a = check() && doSomething();
const flag = cond ? 1 : 0;