`

JavaScript 规范 [es6规范]

 
阅读更多

一、类型规范
二、字符串
三、数组类型
四、解构
五、函数
六、箭头函数
七、对象
八、类
九、模块
十、Iterators 和 Generators(不推荐)
十一、属性访问

 

一、类型规范
对于常量或不修改的变量声明使用const,对于只在当前作用域下有效的变量,应使用let,全局变量使用var。将所有 const 变量放在一起,然后将所有 let 变量放在一起

const foo = 1;

let foo1 = 2;
let bar = foo;
bar = 9;
foo1 = 3;

console.log(foo, bar); // => 1, 9
console.log(foo, bar, str); // => 1, 9,'ouven'

 

const和let使用时注意,let 和 const 都是块作用域的

// const and let only exist in the blocks they are defined in.
{
  let a = 1;
  const b = 1;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError

 

二、字符串
使用单引号 '

// bad
var name = "Bob Parr";

// good
var name = 'Bob Parr';

// bad
var fullName = "Bob " + this.lastName;

// good
var fullName = 'Bob ' + this.lastName;

 

超过80个字符的字符串应该使用字符串连接换行
注:如果过度使用长字符串连接可能会对性能有影响。jsPerf & Discussion

// bad
var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';

// bad
var errorMessage = 'This is a super long error that \
was thrown because of Batman. \
When you stop to think about \
how Batman had anything to do \
with this, you would get nowhere \
fast.';

// good
var errorMessage = 'This is a super long error that ' +
  'was thrown because of Batman.' +
  'When you stop to think about ' +
  'how Batman had anything to do ' +
  'with this, you would get nowhere ' +
  'fast.';

编程构建字符串时,使用字符串模板而不是字符串连接

模板给你一个可读的字符串,简洁的语法与适当的换行和字符串插值特性。

// bad
function sayHi(name) {
  return 'How are you, ' + name + '?';
}

// bad
function sayHi(name) {
  return ['How are you, ', name, '?'].join();
}

// good
function sayHi(name) {
  return `How are you, ${name}?`;
}

 

三、数组类型
 使用字面量语法创建数组

// bad
const items = new Array();

// good
const items = [];

 

如果你不知道数组的长度,使用 push

const someStack = [];

// bad
someStack[someStack.length] = 'abracadabra';

// good
someStack.push('abracadabra');

 

使用 ... 来拷贝数组,不要使用 Array.from、Array.of等数组的新的内置API,因为Babel不容易兼容

// bad
const len = items.length;
const itemsCopy = [];
let i;

for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i];
}

// good
const itemsCopy = [...items];

// error
const foo = [1,2,3];
const nodes = Array.from(foo);

 

四、解构 Destructuring
使用对象的多个属性时请建议使用对象的解构赋值,解构赋值避免了为这些属性创建临时变量或对象。即使转化成es5都是一样的
嵌套结构的对象层数不能超过3层

// not good
let obj = {
  'one': [
    {
      'newTwo': [
        {
          'three': [
            'four': '太多层了,头晕晕'
          ]
        }
      ]
    }
  ]
};

// good
let obj = {
  'one': [
    'two',
    {
      'twoObj': '结构清晰'
    }
  ]
};

 

解构语句中统一不使用圆括号

// not good
[(a)] = [11]; // a未定义
let { a: (b) } = {}; // 解析出错

// good
let [a, b] = [11, 22];

 

对象解构
对象解构元素与顺序无关
对象指定默认值时仅对恒等于undefined ( !== null ) 的情况生效

若函数形参为对象时,使用对象解构赋值

// not good
function someFun(opt) {
  let opt1 = opt.opt1;
  let opt2 = opt.opt2;
  console.log(op1);
}
// good
function someFun(opt) {
  let { opt1, opt2 } = opt;
  console.log(`$(opt1) 加上 $(opt2)`);
}

function someFun({ opt1, opt2 }) {
  console.log(opt1);
}

 

若函数有多个返回值时,使用对象解构,不使用数组解构,避免添加顺序的问题

// not good
function anotherFun() {
  const one = 1, two = 2, three = 3;
  return [one, two, three];
}
const [one, three, two] = anotherFun(); // 顺序乱了
// one = 1, two = 3, three = 2


// good
function anotherFun() {
  const one = 1, two = 2, three = 3;
  return { one, two, three };
}
const { one, three, two } = anotherFun(); // 不用管顺序
// one = 1, two = 2, three = 3

 

已声明的变量不能用于解构赋值(语法错误)

// 语法错误
let a;
{ a } = { b: 123};

 数组解构时数组元素与顺序相关

例如交换数组两个元素的值

let x = 1;
let y = 2;

// not good
let temp;
temp = x;
x = y;
y = temp;

// good
[x, y] = [y, x]; // 交换变量

 

将数组成员赋值给变量时,使用数组解构

const arr = [1, 2, 3, 4, 5];

// not good
const one = arr[0];
const two = arr[1];

// good
const [one, two] = arr;

函数有多个返回值时使用对象解构,而不是数组解构。

这样你就可以随时添加新的返回值或任意改变返回值的顺序,而不会导致调用失败。

function processInput(input) {
    // then a miracle occurs
    return [left, right, top, bottom];
  }

  // the caller needs to think about the order of return data
  const [left, __, top] = processInput(input);

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

  // the caller selects only the data they need
  const { left, right } = processInput(input);

 

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

// bad
const foo = function () {
};

// good
function foo() {
}

 

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

// bad
if (currentUser) {
  function test() {
    console.log('Nope.');
  }
}

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

 

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

// bad
function nope(name, options, arguments) {
  // ...stuff...
}
// good
function yup(name, options, args) {
  // ...stuff...
}

永远不要使用 arguments,使用 ... 操作符来代替

... 操作符可以明确指定你需要哪些参数,并且得到的是一个真实的数组,而不是 arguments 这样的类数组对象。

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

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

 

使用函数参数默认值语法,而不是修改函数的实参

// really bad
function handleThings(opts) {
  opts = opts || {};
}

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

// good
function handleThings(opts = {}) {
  // ...
}

 

六、箭头函数 Arrow Functions
当必须使用函数表达式时(例如传递一个匿名函数时),请使用箭头函数
箭头函数提供了更简洁的语法,并且箭头函数中 this 对象的指向是不变的,this 对象绑定定义时所在的对象,这通常是我们想要的。如果该函数的逻辑非常复杂,请将该函数提取为一个函数声明。

// bad
"use strict";
var fn = function fn(v) {
  return console.log(v);
};
// good
var fn= (v=>console.log(v));

 

箭头函数总是用括号包裹参数,省略括号只适用于单个参数,并且还降低了程序的可读性

// bad
[1, 2, 3].forEach(x => x * x);
// good
[1, 2, 3].forEach((x) => x * x);

 

立即执行的匿名函数
javascript

// 函数表达式
// immediately-invoked function expression (IIFE)
// good,看起来就很厉害
(() => {
console.log('Welcome to the Internet. Please follow me.');
})();

 

七、对象
使用对象字面量创建对象

// bad
var item = new Object();
// good
var item = {};

 

不要使用保留字(reserved words)作为键,否则在 IE8 下将出错

// bad
var superman = {
  class: 'superhero',
  default: { clark: 'kent' },
  private: true
};

// good
var superman = {
  klass: 'superhero',
  defaults: { clark: 'kent' },
  hidden: true
};

 

创建对象时使用计算的属性名,而不要在创建对象后使用对象的动态特性,这样可以在同一个位置定义对象的所有属性。

function getKey(k) {
    return `a key named ${k}`;
  }

  // bad
  const obj = {
    id: 5,
    name: 'San Francisco'
  };
  obj[getKey('enabled')] = true;

  // good
  const obj = {
    id: 5,
    name: 'San Francisco',
    [getKey('enabled')]: true
  };

 

使用定义对象方法的简短形式

// bad
const atom = {
  value: 1,
  addValue: function (value) {
    return atom.value + value;
  }
};

// good
const atom = {
  value: 1,
  addValue(value) {
    return atom.value + value;
  }
};

 

使用定义对象属性的简短形式,书写起来更加简单,并且可以自描述。这里和es5有些不同,需要注意下

const lukeSkywalker = 'Luke Skywalker';

  // bad
  const obj = {
    lukeSkywalker: lukeSkywalker
  };

  // good
  const obj = {
    lukeSkywalker
  };

 

将所有简写的属性写在对象定义的最顶部,这样可以更加方便地知道哪些属性使用了简短形式。

const anakinSkywalker = 'Anakin Skywalker';
const lukeSkywalker = 'Luke Skywalker';

// bad
const obj = {
  episodeOne: 1,
  twoJedisWalkIntoACantina: 2,
  lukeSkywalker,
  episodeThree: 3,
  mayTheFourth: 4,
  anakinSkywalker
};

// good
const obj = {
  lukeSkywalker,
  anakinSkywalker,
  episodeOne: 1,
  twoJedisWalkIntoACantina: 2,
  episodeThree: 3,
  mayTheFourth: 4
};

 

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

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

 

类名与花括号须保留一个空格间距,类中的方法定义时,括号 ) 也须与花括号 { 保留一个空格间距

// not good
class Foo{
  constructor(){
    // constructor
  }
  sayHi()    {
    // 仅保留一个空格间距
  }
}

// good
class Foo {
  constructor() {
    // constructor
  }
  sayHi() {
    // 仅保留一个空格间距
  }
}

 

定义类时,方法的顺序如下:
constructor
public get/set 公用访问器,set只能传一个参数
public methods 公用方法,公用相关命名使用小驼峰式写法(lowerCamelCase)
private get/set 私有访问器,私有相关命名应加上下划线 _ 为前缀
private methods 私有方法

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

// not good
function Foo() {

}
const foo = new Foo();
// good
class Foo {

}
const foo = new Foo();

 

使用 extends 关键字来继承
这是一个内置的继承方式,并且不会破坏 instanceof 原型检查。

// 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来做模块加载

// 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 后面采用花括号{ }引入模块的写法时,建议在花括号内左右各保留一个空格

// not good
import {lightRed} from './colors';
import { lightRed} from './colors';

// good
import { lightRed } from './colors';

 

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

// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';

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

不要直接从一个 import 上 export

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

// bad
// filename es6.js
export default { es6 } from './airbnbStyleGuide';

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

 

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

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

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

export default { a, b };

 

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

// file contents
class CheckBox {
  // ...
}
module.exports = CheckBox;

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

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

// good
const CheckBox = require('./CheckBox');

 

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

function makeStyleGuide() {
}
export default makeStyleGuide;

 

导出单例、函数库或裸对象时,使用大驼峰命名规则

const AirbnbStyleGuide = {
  es6: {
  }
};

 

十、Iterators 和 Generators(不推荐)

不要使用迭代器和生成器,优先使用 JavaScript 中 map 和 reduce 这类高阶函数来代替 for-of 循环
处理纯函数的返回值更加容易并且没有副作用。但是暂时都不要使用

const numbers = [1, 2, 3, 4, 5];
// bad
let sum = 0;
for (let num of numbers) {
  sum += num;
}
sum === 15;

// good
let sum = 0;
numbers.forEach((num) => sum += num);
sum === 15;

// best (use the functional force)
const sum = numbers.reduce((total, num) => total + num, 0);
sum === 15;

 不要使用Iterators 和 generators,它们不太容易转换为 ES5 的语法。

 

十一、属性访问
使用点 . 操作符来访问属性

const luke = {
  jedi: true,
  age: 28
};

// bad
const isJedi = luke['jedi'];

// good
const isJedi = luke.jedi;

 

当使用变量访问属性时使用中括号 []

var luke = {
  jedi: true,
  age: 28
};
function getProp(prop) {
  return luke[prop];
}
var isJedi = getProp('jedi');

 

参考:
http://bubkoo.com/2015/04/05/javascript-style-guide/?utm_source=tuicool
https://github.com/gf-rd/es6-coding-style#%E5%A3%B0%E6%98%8E

 

转载:https://ouvens.github.io/frontend-javascript/2015/10/12/es6-code-style.html

 

分享到:
评论

相关推荐

    JavaScript(ES6新增、W3C、MDN)最新参考手册.zip

    ES6,即ECMAScript 2015,是JavaScript语言的一个重要版本,引入了大量新特性和改进,极大地提升了开发效率和代码质量。W3C(万维网联盟)和MDN(Mozilla开发者网络)都是提供权威JavaScript技术文档和标准的重要...

    JavaScript ES6函数式编程入门经典_javascript_tall7cj_

    此外,模块系统(Modules)是ES6的另一大亮点,它通过`import`和`export`关键字实现模块的导入和导出,使得代码组织更加规范,提高了代码重用性。 总的来说,JavaScript ES6函数式编程入门经典涵盖了从基础语法到...

    JavaScript:ES6新特性:类与模块教程

    ECMAScript 6(简称ES6),是JavaScript的一种规范版本,它带来了一系列重要的新特性,极大地提升了开发者的工作效率和代码的可维护性。本文将重点介绍ES6中两个非常实用的新特性:类与模块。 #### 二、基础知识...

    JavaScript及(ES6)总结

    JavaScript 和 ES6(ECMAScript 6)是前端开发中不可或缺的部分,它们为网页和应用程序提供了动态交互的能力。本文将详细介绍这两个概念以及相关的基础知识。 首先,JavaScript 是一种解释型、动态类型的编程语言,...

    Airbnb+JavaScript+代码规范(ES6)共6

    【标题】"Airbnb+JavaScript+代码规范(ES6)共6" 指的是Airbnb公司制定的一套JavaScript编程规范,特别针对ES6(ECMAScript 2015)版本的语法特性。这套规范旨在提高代码质量和团队协作效率,确保代码的一致性和可...

    JavaScript es6

    ES6 引入了原生的模块系统,使用`import`和`export`关键字进行导入和导出,使得代码组织更加规范: ```javascript // math.js export function add(x, y) { return x + y; } // main.js import { add } ...

    LaTeX_Listings_JavaScript_ES6:LaTeX清单软件包不包含JavaScriptECMAScript的语言规范,这填补了过渡期间的空白

    LaTeX包不包含(默认情况下)JavaScript / ECMAScript的语言规范。 但是,该软件包提供了基于内置方法创建自定义语言和样式的功能。 这些方法用于创建JavaScript和ES6的列表语言(ECMAScript 2015)。 基本...

    ES6 编码规范 - Tower.pdf

    ### ES6编码规范详解 #### 一、类型 **1.1 基本类型** 基本类型可以直接存储和访问,主要包括以下几种: - **字符串**:用于存储文本数据。 - **数值**:用于存储整数或浮点数。 - **布尔类型**:表示逻辑上的真...

    Airbnb出品目前非常流行的JavaScript代码规范中文版

    这份"Airbnb出品目前非常流行的JavaScript代码规范中文版"为国内开发者提供了一个清晰、一致的编程指南,帮助我们写出更规范、更具可读性的JavaScript代码。 1. **命名约定**: - 变量名应清晰反映其用途,使用...

    8小时美女老师带你完全掌握ES6新规范讲解

    **ES6,全称ECMAScript 2015,是JavaScript语言的一个重大更新版本,引入了许多新的特性和语法糖,极大地提升了开发效率和代码的可读性。在这8小时的美女老师课程中,你将深入理解并掌握这些重要的变革。** 首先,*...

    ES6语法规范.docx

    ES6(ECMAScript 6)是一种新的JavaScript语法规范,相比于之前的ES5,ES6带来了许多新的特性和改进。下面将对ES6中的let命令、const命令、解构赋值、Symbol、Set等知识点进行详细的介绍。 一、let命令 let命令是...

    JavaScript中ES6规范中let和const的用法和区别

    在JavaScript的ES6标准中,`let`和`const`是两种新的变量声明方式,它们引入了块级作用域的概念,显著改善了之前`var`存在的问题。下面将详细讲解这两个关键字的用法和区别。 首先,`let`命令允许在块级作用域内...

    深入浅出ES6

    以上内容是对ES6规范的一个概览,旨在为读者提供一个清晰的知识框架,帮助理解ES6在JavaScript语言进化中扮演的角色,以及它引入的众多新特性。通过这些新特性的应用,开发者可以编写更加清晰、高效且易于维护的...

    ES6-基础学习笔记

    ES6 是 ECMAScript 的第六版,发布于 2015 年 6 月,作为 JavaScript 的标准规范。ES6 的出现极大地改变了 JavaScript 的发展方向,引入了许多新的语法特性和功能,提高了 JavaScript 的编程能力和可靠性。本笔记...

    ES6基础知识题

    根据给定的信息,以下是对各个知识点的详细解读: ### ECMAScript规范的理解 - **ECMAScript定义的内容**:...这些知识点涵盖了ES6中的一些核心概念和技术细节,对于理解和掌握现代JavaScript编程至关重要。

    前端开源库-es6ify

    在现代Web开发中,JavaScript的ES6(ECMAScript 6,也称为ES2015)语法以其强大的新特性,如类、模块、箭头函数和模板字符串等,极大地提高了开发效率。然而,由于浏览器对ES6的支持并不完全一致,开发者通常需要将...

Global site tag (gtag.js) - Google Analytics