關於es6的詳細說明,能夠參照個人系列文章es6 從入門到熟練,或者阮一峯的ECMAScript 6 入門。javascript
個人系列文章,是在阮一峯的基礎上,增長了更多適合初中級開發者的內容(包括大量的示例代碼和解釋),以下降學習難度,豐富說明。html
本文是對es6總體的回顧,結合個人實際開發經驗,對es6的一個小結。前端
爲了精煉內容,es6裏不經常使用的內容已經去掉,而對經常使用、重要的es6知識,附上簡單的代碼說明,並另附有詳細說明的博文連接,方便初中級開發者理解。vue
關鍵字:IE九、Babel、Babel的墊片、腳手架java
首先,使用es6的前提是最低IE9,若是你須要兼容IE8,建議放棄es6,專心使用神器jQuery。node
其次,若是須要使用es6來編寫,那麼你須要Babel
轉碼器用於將你的es6代碼轉換爲es5代碼,用於兼容只能使用es5的環境。不然對於只能運行es5的環境(例如IE9),是沒法運行es6代碼的。git
第三,因爲Babel在默認狀況下,並非所有轉換的,如如下說明:es6
Babel 默認只轉換新的 JavaScript 句法(syntax),而不轉換新的 API,好比Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局對象,以及一些定義在全局對象上的方法(好比Object.assign)都不會轉碼。github
所以,咱們須要墊片,通常狀況下能夠用babel-polyfill,也能夠用babel-runtime
,這兩個有所差別。web
babel-polyfill會污染全局對象,即會對例如Object這樣的對象添加方法,而babel-runtime只會轉換es6語法的代碼,但若是你須要調用Object.assign這樣的方法,那就不行了。
因爲細節不少,所以這裏給幾個參考連接吧:
看完以上兩個,可能會以爲應該同時使用這兩個,然而並不須要,看下面這個連接:
transform-runtime 會自動應用 polyfill,即使沒有使用 babel-polyfill的conanliu
於17 Dec 2016
提交的issues。
若是你使用的Vue.js,那麼能夠直接fork個人腳手架,而後當作本身的腳手架使用。
附腳手架連接:vue-scaffold,若是能夠,給個star喔~~
若是你用的不是Vue.js,那麼能夠去搜一下你所使用的框架的腳手架,而後拿來使用。若是找不到,能夠找使用帶腳手架的該框架項目,而後down下來,刪除對方的項目只取殼來用便可。(若是有許可,記得閱讀一下許可看能不能這麼幹)
既然有let和const了,那麼推薦優先使用這兩個。
通常狀況下,let能夠直接替代var,對於常量,能夠用const。
這不是必須的,但用這2個能夠幫你規範寫代碼的習慣,因此仍是強烈推薦的。
比較蛋疼的是,用webtorm,let有時候不會高亮,只有var和const是高亮的。這個多是用的風格的問題,我也不太肯定。解決方案我本身是沒找到,湊合用吧。
另外,let和var之間的一個重要區別是變量提高,因此若是你寫代碼不太規範的話,可能會報錯,好好檢查一下吧。
另外,阮一峯推薦將函數設置爲常量,就像這樣子:
const add = function (a, b) { return a + b }
我以爲挺有道理的,推薦。
既然用es6,固然要用反引號這個高大上的東西了。
詳細用法推薦我本身的博客:ECMAScript 6(7)模板字符串
最基本的用法,能夠直接用反引號替代普通的引號(單引號和雙引號)
例如:
let a = 'ab' // 能夠直接用如下替換 let a = `ab`
並且通常狀況下,簡單需求不用再拼接字符串了~(另外,反引號也能夠像普通字符串那樣拼接)
如:
let str = '20004604'; let html = 'my QQ is ' + str; //用如下替換 let str = '20004604'; let html = `my QQ is ${str}`;
簡單暴力省事。
最大的好處是簡化了寫法,如代碼:
let obj = { a: 1, b: 2 } //old let a = obj.a; let b = obj.b; // es6 let {a, b} = obj
除了對象以外,還有數組也能夠解構賦值,別忘了。
es6的對象,比早期版本的寫起來舒服不少。
例如:
Object.assign()
來合併對象,實現繼承或添加屬性效果;列一些常見寫法:
let obj = { // 對象屬性是函數的時候能夠簡寫 a(){ console.log('對象屬性是函數的時候能夠簡寫') }, // setter和getter的簡寫; get b() { return this._b }, set b(val) { this._b = val } } let c = '添加了一個c' // 經過``Object.assign()``來合併對象,實現繼承或添加屬性效果 // 能夠用變量名只要做爲對象的屬性名,而且變量的值能夠自動成爲對象該屬性名的值 Object.assign(obj, { c }) // 能夠用屬性名錶達式 let d = "abcd" obj[d.replace(/abc/, '')] = '屬性名錶達式'
最經常使用的就兩個:
...
;Array.from()
如代碼:
function getArgs() { let foo = [...arguments] console.log(foo) let bar = Array.from(arguments) console.log(bar) } getArgs(1, 2, 3) // [1, 2, 3] // [1, 2, 3]
須要注意的一個特性:
Array(5)
這樣生成帶空位的數組時,處理他的時候會跳過空位數組的空位;函數經常使用特性有如下幾個:
function test(..args){}
這樣的,這個返回的是一個數組,而不是類數組。function test(a, b = 3) { console.log(a, b) console.log(this) } test.bind('Is this')(1) // 1 3 // Is this function test2(...args) { console.log(args.length) } test2(1, 2, 3, 4, 5) // 5
Set結構最大的特色是去重,Map結構最大的特色是kv結構。
Set:
Set和數組相似,能夠存儲元素,可是Set不能存儲相同的值。
非引用類型變量來講,就是值相等;對於引用類型變量來講,指地址相等(而不是值相等)。詳細狀況請點擊Set類型和WeakSet查看。
至於去重,通常是對數組使用。先做爲參數生成一個Set類型變量,再利用擴展運算符變回數組,去重完成,完美。
利用擴展運算符,調用Set的迭代器接口
// 去重 let foo = new Set([1, 2, 3, 3, 3]) console.log([...foo]); // [1, 2, 3]
Map:
Map結構和對象很是相似,不過最大的區別在於,Map結構能夠用其餘類型做爲key,例如數組、對象等。
Map能夠參照這篇博客Map和WeakMap
示例代碼:
let zhang = { firstName: "王" } let property = { gender: "男" } let foo = new Map() foo.set(zhang, property) foo.has(zhang) // true foo.get(zhang) // {gender: "男"}
Promise是es6的精華之一,他很是適用於異步處理。
Promise對象在使用的時候,分爲兩部分,第一部分是new Promise
這一步,第二部分是對返回的Promise實例進行處理的內容。
由於是經過執行resolve
或reject
來改變Promise的狀態,從而決定執行then的時機的(相似回調函數),以及執行的哪個。所以寫起來和回調函數相近,可是能夠連寫,避免回調地獄的狀況。
關於Promise的詳細介紹請閱讀Promise(1)基礎知識及以後三篇博客
如示例代碼(對比普通ajax和promise)(另注:爲了方便理解,仿jQuery的寫法,而且沒有用jQuery的$.ajax().then()
這種寫法)
// 模擬ajax function ajax (options) { setTimeout(function () { options.success(options.url) }, 1000) } // old let foo = function (callback) { ajax({ url: "/1", success: function (result) { callback(result) } }) } let foo2 = function (result) { console.log(result) return function (callback) { ajax({ url: "/2", success: function (val) { callback(val) } }) } } // 核心,調用的時候若是是連續請求的話,基本要寫成回調地獄了 foo(function (result) { foo2(result)(function (val) { console.log(val) }) }) // Promise let bar = function () { return new Promise((resolve, reject) => { ajax({ url: "/1", success: function (result) { resolve(result) } }) }) } let bar2 = function (result) { console.log(result) return new Promise((resolve, reject) => { ajax({ url: "/2", success: function (val) { resolve(val) } }) }) } // 核心,then連寫便可 bar().then(function (result) { return bar2(result) }).then(function (result) { console.log(result) })
顯然,then連寫比回調函數的寫法要方便一些。
若是面對的是特殊需求,好比是多個ajax請求所有完成後,再執行執行函數,那麼Promise的優點會更大一些,而非Promise寫法要麻煩不少。
甚至若是要對錯誤進行處理,那麼Promise寫法會更方便。
不過這裏只是小結,就不細說了。
class是好東西。
有了class後,寫構造函數、寫類的繼承的難度,降低了不少不少。
先附個人博文class(1)基本概念,以及以後5篇博文。
因爲很簡單,給一個示例大約就能理解這個是怎麼用的:
class Foo { constructor () { console.log('this is constructor') this.defaultValue = '變量要在構造函數裏賦值,而不能直接聲明' } log () { console.log('log') } } let foo = new Foo() // this is constructor foo.log() // log foo.defaultValue // "變量要在構造函數裏賦值,而不能直接聲明"
es6的模塊不一樣於以往的CommonJS(node用,服務器環境),AMD(RequireJS的規範,瀏覽器環境,依賴前置)、CMD(SeaJS定義的規範,瀏覽器環境,依賴就近)。
他的特色有兩個:
缺點是:
詳細說明閱讀這篇博客:es6的import和export,另外三個規範閱讀這篇博客AMD、CMD、CommonJS
基本使用方式如示例代碼:
// foo.js let foo = 'foo' export default foo // bar.js import foo from 'foo' console.log(foo)
這個並非es6的,而是es2017(又稱es8)的內容。
能夠認爲async函數是Generator函數的語法糖,詳細說明參照這篇博客:async函數。
他的前置知識比較多,包括Iterator遍歷器、Generator狀態機、Thunk函數(自動執行Generator 函數)。
簡單的說,假若有多個異步請求,你須要讓這些起步請求依次執行,例如在執行完前一個以後,再執行後一個。那麼你就須要async函數了。
async函數可讓你寫這種請求如同寫同步函數同樣簡單(對比【10】中的Promise更簡單)。
如下示例是基於【10】中的代碼,在最後一步執行的時候,改用async函數來完成
// 模擬ajax function ajax (options) { setTimeout(function () { options.success(options.url) }, 1000) } // Promise let bar = function () { return new Promise((resolve, reject) => { ajax({ url: "/1", success: function (result) { resolve(result) } }) }) } let bar2 = function (result) { console.log(result) return new Promise((resolve, reject) => { ajax({ url: "/2", success: function (val) { resolve(val) } }) }) } async function foo () { let result1 = await bar() let result2 = await bar2(result1) return result2 } foo().then(result => { console.log(result) })
能夠發現,async讓連續異步調用像寫同步函數同樣簡單。
規範化開發,建議仍是用ESLint來幫忙檢查吧。不會這個怎麼行?
ESLint是一個語法規則和代碼風格的檢查工具,能夠用來保證寫出語法正確、風格統一的代碼。
這裏直接給一個阮一峯寫的文章,等之後我再單獨補一篇詳細用法的博客。
es6經常使用內容基本就以上13點。
雖然es6實際包括了不少知識,例如:
但實際經常使用的就以上這些,若是隻是平常使用的話,熟悉以上內容足夠了。
但若要作的更好,那麼應該深刻學習,es6新增的不少內容,是將傳統後端語言的一些很好的思想,搬到JavaScript來,讓js規範化。
對於專精於前端的同窗,學習es6的過程當中,能夠學習到這些來自於其餘語言的精華,所以建議至少完整的看一遍,勿要只知足於經常使用的這些API。