本篇博文参考Airbnb规范制定,有错误或不当请您务必指出
代码风格
导出的默认函数使用驼峰命名、文件名与函数完全一致。
1 | function makeStyleGuide(){ |
导出单例、函数库、空对象时使用帕斯卡式命名(帕斯卡式命名法是在命名的时候将首字母大写, 如: DisplayInfo)。
1 | const AirbnbStyleGuide = { |
类型和变量
变星必须显式声明作用域
- var => 用于声明全局变量或函数级变量
- let => 用于声明块级的局部变量
- const => 声明块级域的只读局部变量。
1 | const names = []; |
在ES6中, const代表一个值的“常量索引”, 换句话说, 变量名字在内存中的指针不能够改变, 但是指向这个变量的值可能改变。
尽量对所有的引用使用const, 不要使用var。 如果你一定需要使用可变动的引用, 使用let代替var。
不好
1 | var a=1; |
好
1 | const a=1; |
说明:const和let的作用域更小, 写代码更容易控制。 const可确保无法对引用重新赋值, const引用的指针不变, 重新赋值会报错, 避免不小心的重新赋值给覆盖了。
将所有的const和let分组,并隔行
不好
1 | let i; |
好
1 | const flag=true; |
在需要的地方给变量 赋值, 但请把它们放在一个合理的位置。
说明:let和const是作用域而不是函数作用域, 不用担心变量定义会被前移导致问题, 把变量的赋值和调用代码放在一起会使逻辑更加清晰, 可读性更好。
不好
1 | function(name){ |
好
1 | function(name){ |
对象和引用
创建有动态属性名的对象时, 尽量在一个地方定义对象的所有属性。
不好
1 | const obj={ |
好
1 | const obj={ |
使用对象方法的简写。
说明:ES6中, 对象字面量被增强了, 写法更加简洁与灵活, 同时在定义对象的时候, 能够做的事件更多了。
不好
1 | const atom = { |
好
1 | const atom = { |
使用对象属性的简写
不好
1 | const obj = { |
好
1 | const obj = { |
数组
使用扩展运算符 … 复制数组
扩展运算符可以减少赋值语句的使用, 或者减少通过下标访问数组或对象的方式, 使用代码更加简洁优雅, 可读性更佳。
不好
1 | const len = items.length; |
好
1 | const itemsCopy = [...items]; |
属性
使用 . 来访问对象的属性, 只有属性是动态的时候使用 []。
1 | const key=getKey(); |
逗号、分号
逗号写在行尾, 并且增加结尾的逗号。
不好
1 | const obj = { |
好
1 | const obj = { |
使用分号, 以分号作为语句的结束符。
1 | ;(()=>{ |
函数
使用函数声明代替函数表达式
说明:因为函数声明是可命名的, 所以他们在调用栈中更容易被识别。 此外, 函数声明会把整个函数提升, 而函数表达式只会把函数引用的变量名提升。 这条规则使得箭头函数可以取代函数表达式。
不好
1 | const function = foo(){ |
好
1 | function foo(){ |
不要使用arguments, 可以选择rest语法 … 替代。
说明:使用 … 能明确你要传入的参数, 另外, rest语法参数是一个真正的数组, 而arguments是一个类数组。
不好
1 | function concatenateAll() { |
好
1 | function concatenateAll(...args) { |
直接给函数的参数指定默认值, 不要使用一个变化的函数参数。
1 | function handle(opts={}){ |
直接给函数参数赋值时, 需要避免副作用。
不好
1 | var b=1; |
代码块
使用大括号包裹所有的多行代码块。
不好
1 | if(true) |
好
1 | if(true) return false; |
- 如果通过if和else使用多行代码块, 把else放在if代码块关闭括号的同一行。
不好
1 | if(arg) { |
好
1 | if(arg) { |
模块
代码中总是使用ES6标准的模块(import/export)方式, 而不是使用非标准的模块加载器。
不好
1 | const AirbnbStyleGuide=require('./AirbnbStyleGuide'); |
好
1 | import AirbnbStyleGuide from '/AirbnbStyleGuide'; |
更好
1 | import { es6 } from '/AirbnbStyleGuide'; |
不要使用通配符 *的import 。
说明:这样可以确保被import的模块只有一个默认的export项。
不好
1 | import * as AirbnbStyleGuide from '/AirbnbStyleGuide'; |
好
1 | import AirbnbStyleGuide from '/AirbnbStyleGuide'; |
不要从import中直接export.
不好
1 | export {es6 as defaults} from './ablier.js'; |
好
1 | import {es6} from './ablier.js'; |
如果你的文件只输出一个类, 那你的文件名必须和类名完全保持一致。
1 | import CheckBox from './CheckBox'; |
箭头函数
别保存this的引用, 使用箭头函数或Function.bind。
说明:箭头函数提供了更简洁的语法, 并且箭头函数中的this对象指向是不变的, this绑定到定义时所在的对象。 通常情况下, 这是我们想要的, 有很好的代码可读性, 而保存this对象的使用方式, 会让开发人员搞混。
不好
1 | function foo(){ |
好
1 | function foo(){ |
当你必须使用函数表达式(或传递一个匿名函数)时, 使用箭头函数。
说明:箭头函数创造了一个新的this执行环境。 通常情况下, 能满足你的需求, 而且这样的写更为简洁。 如果你有一个相当复杂的函数, 那么可以把逻辑部分转移到一个函数声明上。
不好
1 | [1, 2, 3].map(function(x) { |
好
1 | [1, 2, 3].map( (x) => { |
如果一个函数适用一行写出并且只有一个参数, 那就把花括号、圆括号和return都省略掉, 如果不是, 那就不要省略。
好
1 | [1, 2, 3].map( x => x * x;); |
构造器
采用class关键字定义类
不好
1 | function Queue(contents=[]{ |
好
1 | class Queue{ |
采用extends关键字实现继承。
说明:因为extends是内建的继承方式, 并不会破坏instanceof原型检查。
不好
1 | const inherits=require('inherits'); |
好
1 | class peekableQueue extends Queue{ |
解构
使用解构存取和使用多属性对象。
说明:ES6允许按照一定的模式, 从数组和对象中提取值、对变量进行赋值, 这称之为解构, 解构赋值避免了临时变量或对象, 给JavaScript书写带来了很大的便利性, 同时也提高了代码的可读性。
不好
1 | function getFullName (user) { |
好
1 | function getFullName ({firstName, lastName}) { |
将数组成员赋值给变量时, 使用数组解析。
不好
1 | const arr = [1,2,3] |
好
1 | const [first, second]=arr; |
需要回传多个值时, 使用对象解构, 而不是数组解构。
说明:对象解构在增加属性或改变排序时, 无需改变调用时的位置。
不好
1 | function input(inputType){ |
好
1 | // 调用时候只选择需要的数据 |
String
长度超过80的字符串应该使用字符串连接换行。
构建字符串时, 使用字符串模板而不是字符串连接。
好
1 | function sayHi(name) { |
数组遍历采用for/of, 对象遍历采用for/in。
不好
1 | let arr = [1, 2, 3, 4]; |
好
1 | let arr = [1, 2, 3, 4]; |
存取器
属性的存取函数不是必须的, 如果需要存储函数使用get方法和set方法。 如果属性是布尔值, 存取函数是isVal()或hasVal()。
不好
1 | dragon.age(); |
好
1 | dragon.getAge(); |
创建get()和set()函数要保持一致。
好
1 | class Demo { |