ES6的平常一些功能

一、前注

關於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這樣的方法,那就不行了。

因爲細節不少,所以這裏給幾個參考連接吧:

Babel 全家桶

babel的polyfill和runtime的區別

看完以上兩個,可能會以爲應該同時使用這兩個,然而並不須要,看下面這個連接:

transform-runtime 會自動應用 polyfill,即使沒有使用 babel-polyfillconanliu17 Dec 2016提交的issues。

若是你使用的Vue.js,那麼能夠直接fork個人腳手架,而後當作本身的腳手架使用。

附腳手架連接:vue-scaffold,若是能夠,給個star喔~~

若是你用的不是Vue.js,那麼能夠去搜一下你所使用的框架的腳手架,而後拿來使用。若是找不到,能夠找使用帶腳手架的該框架項目,而後down下來,刪除對方的項目只取殼來用便可。(若是有許可,記得閱讀一下許可看能不能這麼幹)

三、let和const

既然有let和const了,那麼推薦優先使用這兩個。

通常狀況下,let能夠直接替代var,對於常量,能夠用const。

這不是必須的,但用這2個能夠幫你規範寫代碼的習慣,因此仍是強烈推薦的。

比較蛋疼的是,用webtorm,let有時候不會高亮,只有var和const是高亮的。這個多是用的風格的問題,我也不太肯定。解決方案我本身是沒找到,湊合用吧。

另外,let和var之間的一個重要區別是變量提高,因此若是你寫代碼不太規範的話,可能會報錯,好好檢查一下吧。

另外,阮一峯推薦將函數設置爲常量,就像這樣子:

const add = function (a, b) { return a + b }
  • 1
  • 2
  • 3

我以爲挺有道理的,推薦。

四、字符串

既然用es6,固然要用反引號這個高大上的東西了。

詳細用法推薦我本身的博客:ECMAScript 6(7)模板字符串

最基本的用法,能夠直接用反引號替代普通的引號(單引號和雙引號)

例如:

let a = 'ab' // 能夠直接用如下替換 let a = `ab`
  • 1
  • 2
  • 3

並且通常狀況下,簡單需求不用再拼接字符串了~(另外,反引號也能夠像普通字符串那樣拼接)

如:

let str = '20004604'; let html = 'my QQ is ' + str; //用如下替換 let str = '20004604'; let html = `my QQ is ${str}`;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

簡單暴力省事。

五、解構賦值

最大的好處是簡化了寫法,如代碼:

let obj = { a: 1, b: 2 } //old let a = obj.a; let b = obj.b; // es6 let {a, b} = obj
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

除了對象以外,還有數組也能夠解構賦值,別忘了。

六、對象

es6的對象,比早期版本的寫起來舒服不少。

例如:

  1. 對象屬性是函數的時候能夠簡寫;
  2. setter和getter的簡寫;
  3. 經過Object.assign()來合併對象,實現繼承或添加屬性效果;
  4. 能夠用屬性名錶達式;
  5. 能夠用變量名只要做爲對象的屬性名,而且變量的值能夠自動成爲對象該屬性名的值;

列一些常見寫法:

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/, '')] = '屬性名錶達式'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

七、數組

最經常使用的就兩個:

  1. 擴展運算符...
  2. 將類數組的轉爲數組的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]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

須要注意的一個特性:

  1. es5在面對,經過Array(5)這樣生成帶空位的數組時,處理他的時候會跳過空位數組的空位
  2. es6在一樣狀況下,由於使用遍歷器接口,因此會進行處理(視爲undefined),而不是跳過;

八、函數

函數經常使用特性有如下幾個:

  1. 箭頭函數:特色是this永遠指向聲明時的父級做用域,寫起來比普通函數簡單;
  2. bind:能夠給函數綁定this,並將這個綁定後的函數返回(不影響原函數);
  3. rest函數:即函數參數使用例如function test(..args){}這樣的,這個返回的是一個數組,而不是類數組。
  4. 參數默認值:通常帶默認值的參數,放在參數列表的後面。
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

九、Set和Map

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]
  • 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: "男"}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

十、Promise

Promise是es6的精華之一,他很是適用於異步處理。

Promise對象在使用的時候,分爲兩部分,第一部分是new Promise這一步,第二部分是對返回的Promise實例進行處理的內容。

由於是經過執行resolvereject來改變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) })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

顯然,then連寫比回調函數的寫法要方便一些。

若是面對的是特殊需求,好比是多個ajax請求所有完成後,再執行執行函數,那麼Promise的優點會更大一些,而非Promise寫法要麻煩不少。

甚至若是要對錯誤進行處理,那麼Promise寫法會更方便。

不過這裏只是小結,就不細說了。

十一、class

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 // "變量要在構造函數裏賦值,而不能直接聲明"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

十二、es6模塊

es6的模塊不一樣於以往的CommonJS(node用,服務器環境),AMD(RequireJS的規範,瀏覽器環境,依賴前置)、CMD(SeaJS定義的規範,瀏覽器環境,依賴就近)。

他的特色有兩個:

  1. 編譯時加載,所以能夠作靜態優化;
  2. 模塊的引用進來的,都是值的引用,而非值的拷貝。

缺點是:

  1. 瀏覽器環境下不支持,node環境下支持的也比較差;
  2. 必須考babel轉碼後才能夠正常使用,所以對某些符合規範的特性支持的不是很好;

詳細說明閱讀這篇博客:es6的import和export,另外三個規範閱讀這篇博客AMD、CMD、CommonJS

基本使用方式如示例代碼:

// foo.js let foo = 'foo' export default foo // bar.js import foo from 'foo' console.log(foo)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1三、async函數

這個並非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) })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

能夠發現,async讓連續異步調用像寫同步函數同樣簡單。

1四、ESLint

規範化開發,建議仍是用ESLint來幫忙檢查吧。不會這個怎麼行?

ESLint是一個語法規則和代碼風格的檢查工具,能夠用來保證寫出語法正確、風格統一的代碼。

這裏直接給一個阮一峯寫的文章,等之後我再單獨補一篇詳細用法的博客。

ESLint的使用

1五、小結

es6經常使用內容基本就以上13點。

雖然es6實際包括了不少知識,例如:

  1. string方面增長了對utf16字符的更好的支持;
  2. number方面增長了對最大值、最小值、以及合理偏差偏差值的處理等;
  3. Symbol產生惟一變量;
  4. Proxy的代理;
  5. 遍歷器,狀態機等等。

但實際經常使用的就以上這些,若是隻是平常使用的話,熟悉以上內容足夠了。

但若要作的更好,那麼應該深刻學習,es6新增的不少內容,是將傳統後端語言的一些很好的思想,搬到JavaScript來,讓js規範化。

對於專精於前端的同窗,學習es6的過程當中,能夠學習到這些來自於其餘語言的精華,所以建議至少完整的看一遍,勿要只知足於經常使用的這些API。

相關文章
相關標籤/搜索