- 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的方法,如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()作浅拷贝 //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 = [];
//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]
//当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'javascript
//bad let str = 'hello '+name+' !'; //good let str =`hello ${name} !`;
//bad let foo= function(){} function foo(){} //good let foo = function getPageFooComponent(){} //use foo();
//bad if(){ function test(){} } //good let test; if(){ test = ()=>{console.log("hello")} }
//bad function foo(name,arguments){} //good function foo(name,arg){}
//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){ }
//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; } }
//good class Dog extends Animal{ yell(){ return 'wangwang' } }
//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);
//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' } }
//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;
//bad import * as AirbnbJavascriptGuide from './AirbnbJavascriptGuide '; //good import AirbnbJavascriptGuide from './AirbnbJavascriptGuide ';
//bad export { es6 as default } from './AirbnbJavascriptGuide '; //good import { es6 } from './AirbnbJavascriptGuide '; export default es6;
//bad import foo form 'foo'; ... import { name,age } from 'foo'; //good import foo,{ name,age } form 'foo'; //best import foo,{ name, age } form 'foo';
//bad export function foo() {} //good export default foo() {}
//bad import foo from 'css!sass!foo.scss'; //good import foo from 'foo.css';
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);
//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')
##变量##css
//good let superPower = new SuperPower();
//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... }
// badjava
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; }
// badgit
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 });
// bad const sidebar = $('.sidebar'); // good const $sidebar = $('.sidebar');
const $sidebar = $('.sidebar');
$('.sidebar ul') $('.sidebar > ul')
// bad $('ul', '.sidebar').hide(); // good $sidebar.find('ul').hide(); 参考: https://github.com/airbnb/javascript