类型
基本类型
- string
- number
- boolean
- null
- undefined
- symbol(表示独一无二的值,使用时需要注意浏览器是否支持)
//example
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
console.log(typeof symbol1);
// expected output: "symbol"
console.log(symbol3.toString());
// expected output: "Symbol(foo)"
console.log(Symbol('foo') === Symbol('foo'));
// expected output: false
复杂类型
- array
- object
- function
声明变量
//块级作用域内有效
- let
//块级作用域内有效 不可重复赋值
- const
对象
直接声明
//bad
let obj = new Object();
//good
let obj = {};
动态属性名
//bad
function getKey(key){
return `${key}`
}
let obj = {
id:1
name:"jack"
}
obj[getKey("age")] = 18;
console.log(obj.age) //18
//good
let obj = {
name:"jack",
age:18,
[getKey("age")]:18
}
对象方法简写
//bad
let obj = {
name:"jack",
age:18,
show:function(arg){
console.log(arg)
}
}
//good
let obj = {
name:"jack",
age:18,
show(arg){
console.log(arg)
}
}
属性值简写
//bad
let age = 18;
let obj = {
name:"jack",
age:age
}
//good
let obj = {
age,//简写最好放前面
name:"jack",
"data-id":5//键名尽量不加引号,除非没有引号不合法
}
不要直接使用Object.prototype的方法
//不要直接使用Object.prototype的方法,如hasOwnProperty, propertyIsEnumerable和isPrototypeOf
//bad
let obj = {
id:1,
name:"jack"
}
obj.hasOwnProperty("name");
//good
Object.prototype.hasOwnProperty.call(obj,"name");
//best
var has = Object.prototype.hasOwnProperty;
has.call(obj,"name")
用变量的解构赋值代替Object.assign()做浅拷贝
//用变量的解构赋值代替Object.assign()做浅拷贝
//bad
let ori = {a:1,b:2};
let copy = Object.assign({},ori,{c:3});
//good
let ori = {a:1,b:2};
let copy = {...ori,c:3};//{a:1,b:2,c:3}
let {a,...notA} = copy; // notA={b:2,c:3}
数组
简洁声明
//bad
let arr = new Array();
//good
let arr = [];
使用push代替直接分配元素给数组
//bad
let arr = [];
arr[arr.length] = "abc";
//good
arr.push("abc");
扩展运算符...代替数组拷贝
//bad
let arr = [1,2,3];
let copy = [];
for(let i=0;i<len=arr.length,i++){
copy[i] = arr[i]
}
//good
copy = [...arr]
转换类数组的对象为数组
let div = document.querySelectAll("div");
//good
let arr = Array.from(div);
//best
let arr = [...div]
数组方法中的return
//当function大括号只有一个表达式时,{}和rerun都可以省
//bad
[1,2,3].map(x=>{
let y = x+1;
return x*y
})
//good
[1,2,3].map(x=>x+1)
解构赋值
//object
//good
function getFullName(user){
let {firstName,lastName} = user;
return `${firstName}${lastName}`
}
//best
function getFullName({firstName,lastName}){
return `${firstName}${lastName}`
}
//array
let arr = [1,2,3,4];
//bad
let first = arr[0];
let sec = arr[1];
//good
[first,sec] = arr
函数的多个返回值用对象解构赋值
//bad
function processInput(input){
return [let,top,right,bottom]
}
//good
function processInput(input){
return {let,top,right,bottom}
}
//use
let {left,bottom} = processInput(input);
字符串
使用单引号
//bad
let str = "hello world";
//good
let str = 'hello world'
尽量别转行
//有转行时,当然字符数不超过100的情况尽量别转行
//bad
let str = 'hello world,'+
'balabalabala';
//good
let str = 'hello world,balabalabala'
字符串变量拼接
//bad
let str = 'hello '+name+' !';
//good
let str =`hello ${name} !`;
函数
复杂名称的函数赋值给一个简洁变量名
//bad
let foo= function(){}
function foo(){}
//good
let foo = function getPageFooComponent(){}
//use
foo();
别在if while等语句中声明函数
//bad
if(){
function test(){}
}
//good
let test;
if(){
test = ()=>{console.log("hello")}
}
别用arguments作为参数名
//bad
function foo(name,arguments){}
//good
function foo(name,arg){}
扩展运算符...代替arguments
//bad
function test(){
let args = Array.portotype.slice.call(arguments);
return args.join('');
}
//good
function test(...args){
return args.join('');
}
默认参数
//bad
funtion test(opt){
let opt = opt || {}
}
//good
function test(opt={}){
}
别在参数体里面计算
//bad
let a=1;
function test(b = a++){
}
将赋值的参数放在最后
//bad
function test(opt = {},name){
}
//good
function test(name,opt = {}){
}
别对参数重新赋值
//bad
function test(a){
let a=1;
}
function test(a){
if(!a){
let a=1;
}
}
//good
function test(a){
let b = a || 1;
}
function test(a = 1){
}
类&构造方法
用class代替传统的prototype手动方法
//bad
function Queue(contents = []){
this.queue = [contents];
}
Queue.prototype.pop = function(){
let value = this.queue[0];
this.queue.spice(0,1);
return value;
}
//good
class Queue {
constructor(contents = []){
this.queue = [contents]
}
pop(){
let value = this.queue[0];
this.queue.spice(0,1);
return value;
}
}
用extend做继承
//good
class Dog extends Animal{
yell(){
return 'wangwang'
}
}
this的指向
//bad
Jedi.prototype.jump = function(){
this.jumping = true;
return true;
}
Jedi.prototype.setHeight= function(height){
this.height = height;
}
let luck = new Jedi();
luck.jump();
luck.setHeight(20);
//good
class Jedi{
jump(){
this.jumping = true;
return true;
}
setHeight(height){
this.height = height;
}
}
let luck = new Jedi();
luck.jump();
luck.setHeight(20);
子类的构造函数必须执行一次super函数
//bad
class test {
constructor() {}//空constructor不需要
getName() {
return this.name;
}
}
//bad
class test {
constructor(...args) {
super(...args)//只是为了继承constructor不需要
}
}
//good
class test {
constructor(...args) {
super(...args)
this.name = 'key'
}
}
模块
import/export
//bad
let AirbnbJavascriptGuide = require('./AirbnbJavascriptGuide ');
module.exports = AirbnbJavascriptGuide.es6;
//ok
import AirbnbJavascriptGuide from './AirbnbJavascriptGuide ';
export default AirbnbJavascriptGuide.es6;
//best
import {es6} from './AirbnbJavascriptGuide ';
export default es6;
忌用通配符import
//bad
import * as AirbnbJavascriptGuide from './AirbnbJavascriptGuide ';
//good
import AirbnbJavascriptGuide from './AirbnbJavascriptGuide ';
别在import时同时export
//bad
export { es6 as default } from './AirbnbJavascriptGuide ';
//good
import { es6 } from './AirbnbJavascriptGuide ';
export default es6;
同一个地址放在一个import
//bad
import foo form 'foo';
...
import { name,age } from 'foo';
//good
import foo,{ name,age } form 'foo';
//best
import foo,{
name,
age
} form 'foo';
只有一个export时 用export default
//bad
export function foo() {}
//good
export default foo() {}
不要在import时用Webpack loader
//bad
import foo from 'css!sass!foo.scss';
//good
import foo from 'foo.css';
迭代遍历
用map、every、filter,find,findIndex,some,reduce等代替for-in,for-of
let numbers = [1,2,3,4]
//bad
let sum = 0;
for(let num of numbers){
sum += num;
}
//good
let sum = 0;
numbers.forEach(num => sum += num);
//bad
let increaseByOne = [];
for(let i = 0;i< numbers.length;i++){
increaseByOne .push(numbers[i]+1);
}
//good
let increaseByOne = numbers.map(num => num + 1);
正确的constructor的书写
//good
let test = function* (){
//...
}
属性
通过.访问属性
let luke = {
jedi:true,
age:28
}
//bad
let isJedi = luke['jedi'];
//good
let isJedi = luke.jedi;
通过变量访问属性时使用中括号 []
let luke = {
jedi:true,
age:28
}
function getProp(prop) {
return luke[prop];
}
let isJedi = getProp('jedi')
##变量##
用let和const声明变量
//good
let superPower = new SuperPower();
提升
var 声明会被提升至该作用域的顶部,但它们赋值不会提升
//bad
// 由于变量提升的原因,
// 在引用变量后再声明变量是可以运行的。
// 注:变量的赋值 `true` 不会被提升。
function example() {
console.log(declaredButNotAssigned); // => undefined
var declaredButNotAssigned = true;
}
匿名函数表达式的变量名会被提升,但函数内容并不会
function example() {
console.log(anonymous); // => undefined
anonymous(); // => TypeError anonymous is not a function
var anonymous = function() {
console.log('anonymous function expression');
};
}
函数声明的名称和函数体都会被提升
function example() {
superPower(); // => Flying
function superPower() {
console.log('Flying');
}
}
比较和等号
优先使用 === 和 !== 而不是 == 和 !=
//good
if(a===1){}
使用简写
// bad
if (name !== '') {
// ...stuff...
}
// good
if (name) {
// ...stuff...
}
// bad
if (collection.length > 0) {
// ...stuff...
}
// good
if (collection.length) {
// ...stuff...
}
三元运算符通写在一行
// bad
const foo = maybe1 > maybe2
? "bar"
: value1 > value2 ? "baz" : null;
// split into 2 separated ternary expressions
const maybeNull = value1 > value2 ? 'baz' : null;
// better
const foo = maybe1 > maybe2
? 'bar'
: maybeNull;
// best
const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
避免不必要的三元运算符
// bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;
// good
const foo = a || b;
const bar = !!c;
const baz = !c;
混合运算时,尽量用括号,易懂
//bad
if(a || b && c){
//...
}
//good
if(a || (b && c)){
//...
}
代码块
用大括号包裹所有的多行代码块
// bad
if (test)
return false;
// good
if (test){
return false;
}
条件语句
条件语句,换行将运算符放在最前面
// bad
if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {
thing1();
}
//good
if (
(foo === 123 || bar === 'abc')
&& doesItLookGoodWhenItBecomesThatLong()
&& isThisReallyHappening()
) {
thing1();
}
注释
- 使用 /** ... */ 作为多行注释
- 使用 // 作为单行注释 ,上方空一行
- 使用 // FIXME: 标注问题
- 使用 // TODO: 标注问题的解决方式
逗号
- 行首逗号:不需要
- 结尾的逗号: 需要
分号
- 别省略分号
类型转换
字符串
// bad
const totalScore = new String(this.reviewScore); // typeof totalScore is "object" not "string"
// bad
const totalScore = this.reviewScore + ''; // invokes this.reviewScore.valueOf()
// bad
const totalScore = this.reviewScore.toString(); // isn’t guaranteed to return a string
// good
const totalScore = String(this.reviewScore);
数字
let inputValue= 4;
// bad
const val = new Number(inputValue);
// bad
const val = +inputValue;
// bad
const val = inputValue >> 0;
// bad
const val = parseInt(inputValue);
// good
const val = Number(inputValue);
// good
const val = parseInt(inputValue, 10);
布尔
const age = 0;
// bad
const hasAge = new Boolean(age);
// good
const hasAge = Boolean(age);
// good
const hasAge = !!age;
命名规则
- 避免单字母命名。命名应具备描述性
- 使用驼峰式命名对象、函数和实例
- 使用ES6命名构造函数或类
class User {
constructor(options) {
this.name = options.name;
}
}
let good = new User({
name:"yup"
});
- 使用下划线 _ 开头命名私有属性
- 使用箭头函数避免this引用错误
//bad
function test(){
let self = this;
return function(){
console.log(self);
}
}
//good
function test(){
return ()=>{
console.log(this);
}
}
- 文件只输出一个类,文件名必须和类名完全保持一致
// file contents
class CheckBox {
// ...
}
export default CheckBox;
// in some other file
// bad
import CheckBox from './checkBox';
// bad
import CheckBox from './check_box';
// good
import CheckBox from './CheckBox';
存取器
- 使用好get、set
- is、has
- 保持一致
// bad
dragon.age();
// good
dragon.getAge();
// bad
if (!dragon.age()) {
return false;
}
// good
if (!dragon.hasAge()) {
return false;
}
事件
// bad
$(this).trigger('listingUpdated', listing.id);
...
$(this).on('listingUpdated', function(e, listingId) {
// do something with listingId
});
// good
$(this).trigger('listingUpdated', { listingId : listing.id });
...
$(this).on('listingUpdated', function(e, data) {
// do something with data.listingId
});
jQuery
使用 $ 作为存储 jQuery 对象的变量名前缀
// bad
const sidebar = $('.sidebar');
// good
const $sidebar = $('.sidebar');
缓存 jQuery 查询
const $sidebar = $('.sidebar');
对 DOM 查询使用层叠
$('.sidebar ul')
$('.sidebar > ul')
对有作用域的 jQuery 对象查询使用 find
// bad
$('ul', '.sidebar').hide();
// good
$sidebar.find('ul').hide();
参考:
https://github.com/airbnb/javascript
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。