- 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