ES2015實(shí)戰(zhàn)——面向未來(lái)編程

2018-06-16 20:41 更新

昨天在知識(shí)體系做了一次分享,主題是ES2015實(shí)戰(zhàn),本文將分享內(nèi)容整理成博文,幫助沒(méi)記住,沒(méi)聽(tīng)懂和錯(cuò)過(guò)的同學(xué)來(lái)看,同時(shí)也分享給大家,分享給更多的人。

本文基本是對(duì)分享內(nèi)容的總結(jié),但可能略有差異,或者說(shuō)文字內(nèi)容都是經(jīng)過(guò)精雕細(xì)琢的,不會(huì)有分享現(xiàn)場(chǎng)的錯(cuò)誤,所以說(shuō)絕對(duì)值得一看。

開(kāi)始之前警告一下,內(nèi)容不少,建議略作準(zhǔn)備,讓我們開(kāi)始我們的探險(xiǎn)之旅吧,let’s go。

本文的大綱如下,和分享內(nèi)容一致:

  • 開(kāi)場(chǎng)
  • 道歉
  • 關(guān)于我
  • 歷史
  • 新特性
  • 實(shí)戰(zhàn)
  • 未來(lái)
  • 總結(jié)
  • 選擇
  • 參考資料
  • 問(wèn)答
  • 彩蛋

注:蛋疼的markdown并不支持錨點(diǎn),還得手動(dòng)寫(xiě)html,所以我就不加了,我是純粹主義者,不能接受在markdown里插入html(其實(shí)是太懶),大家順著往下看吧。

說(shuō)明:每個(gè)大標(biāo)題相當(dāng)于上面的大綱,每個(gè)二級(jí)標(biāo)題相當(dāng)于ppt的一頁(yè)(這把ppt搞成文章還真是不太容易)。

開(kāi)場(chǎng)

為了等大家的到來(lái)(總有人喜歡遲到),避免先到同學(xué)的無(wú)聊,我專門(mén)給大家準(zhǔn)備了一個(gè)開(kāi)場(chǎng)小游戲。

相關(guān)鏈接:

道歉

先給大家道個(gè)歉,這個(gè)分享本來(lái)打算趕在15年分享,因?yàn)?5年剛好是Web誕生25周年,也剛剛好是我的25周歲,我竟然和web同歲(沾沾嘻嘻),但拖延癥很?chē)?yán)重的我,一直拖到現(xiàn)在,直到開(kāi)講前的半小時(shí)我還在改ppt,我希望給大家最好的分享。

PS:其實(shí)我還專門(mén)買(mǎi)了本《戰(zhàn)勝拖延癥》的書(shū),但一直拖到現(xiàn)在還沒(méi)時(shí)間看,o(╯□╰)o

關(guān)于我

先做個(gè)自我介紹,這里不展開(kāi)了,感興趣的同學(xué)直接點(diǎn)這里。

我的前端啟蒙

10年開(kāi)始接觸前端,一路走來(lái)到現(xiàn)在剛好5年多一點(diǎn),說(shuō)起我的前端入門(mén)就像笑話一樣,一路自己摸索過(guò)來(lái)。

開(kāi)始時(shí)為了給安裝包寫(xiě)說(shuō)明文檔,我想讓我的說(shuō)明文檔更漂亮,所以用到了html,對(duì)沒(méi)錯(cuò)就是這么low,如下圖中的許可協(xié)議。

我其實(shí)是像下面這樣寫(xiě)的,現(xiàn)在看low到爆,但我當(dāng)時(shí)覺(jué)得簡(jiǎn)直就是完美啊。

<font size="24">許可協(xié)議</font>

我的前端啟蒙書(shū)

為了制作安裝包的文檔,我覺(jué)得我得學(xué)學(xué)HTML,這個(gè)東西看起來(lái)不錯(cuò)啊,比C語(yǔ)言那個(gè)黑框框好多了,然后我就去了圖書(shū)館挑來(lái)挑去我就調(diào)到了下面這本書(shū),我之所以挑下面是這本書(shū),是因?yàn)檫@本書(shū)是彩色的,比較好看,當(dāng)時(shí)也不懂,也沒(méi)想那么多。

當(dāng)時(shí)也看到了網(wǎng)頁(yè)三劍客之類(lèi),如果但是入了三劍客的門(mén)可能就不能在這里給大家分享了,我可能去做flash了。

好像也很low,囧。

相關(guān)鏈接:

我的處女作

前段時(shí)間我在微博曬了我的處女作,引發(fā)了很多曬出自己的第一個(gè)作品,今天在整理這個(gè)ppt的時(shí)候,我發(fā)現(xiàn)了我更早的一個(gè)前端作品。

三個(gè)frame,也是不能更low了,我放這個(gè)當(dāng)然不是讓大家看我都low,而是想告訴大家web強(qiáng)大的兼容能力,html5中frame已經(jīng)廢棄了,但是瀏覽器仍然能夠支持,20年前的網(wǎng)頁(yè)如今依然能看,這么強(qiáng)大的平臺(tái),承擔(dān)人類(lèi)知識(shí)的傳播者,簡(jiǎn)直就是再適合不過(guò)了。

強(qiáng)大的兼容性,得已于html和css的設(shè)計(jì)理念,設(shè)計(jì)之初就是向后兼容的,不認(rèn)識(shí)的標(biāo)簽識(shí)別為行內(nèi)元素,不認(rèn)識(shí)的css屬性直接忽略,而不是報(bào)錯(cuò)。

我的前端路

再來(lái)說(shuō)說(shuō)我的前端路,我10年接觸前端,因?yàn)槲抑饕强磳W(xué)校圖書(shū)館的書(shū)來(lái)學(xué)習(xí)前端的,雖說(shuō)09年HTML5已經(jīng)定稿,但國(guó)內(nèi)的環(huán)境其實(shí)會(huì)之后1年,然后國(guó)內(nèi)圖書(shū)一般會(huì)之后2-3年,然后圖書(shū)館的書(shū)一般會(huì)再落后1年,這一下就落后了5年,也就是說(shuō)我開(kāi)始時(shí)并不知道哪些書(shū)特別好,所以我最看是看到的都是03年左右的書(shū),后來(lái)看得多了才慢慢知道了選擇哪些書(shū),所以我10年入門(mén)卻還是經(jīng)歷了很多技術(shù)上的變革。

寫(xiě)著寫(xiě)著突然發(fā)現(xiàn)這部分簡(jiǎn)直可以單獨(dú)寫(xiě)一篇文章了,╮(╯▽╰)╭。

先來(lái)說(shuō)說(shuō)我經(jīng)歷HTML變革如下:

  • HTML 4
  • xhtml 1.1
  • html 5
  • html
  • html 5.1

我最開(kāi)始接觸的是html4,我特別不能認(rèn)識(shí)大寫(xiě)的英文,比如strong我認(rèn)識(shí),但是STRONG我要先寫(xiě)成小寫(xiě)才能認(rèn)識(shí),所以我特別討厭大寫(xiě)的標(biāo)簽;后來(lái)接觸了xhtml,感覺(jué)這個(gè)真是好啊,至少要求全部小寫(xiě)啊,這么嚴(yán)格的要求我特別喜歡,并奉為至尊。

再到后來(lái)xhtml2 失敗,html5更空出世充當(dāng)救世主,坐在我對(duì)面的舍友告訴我html5來(lái)了,標(biāo)簽又能大寫(xiě)了,也不用閉合,屬性也不用雙引號(hào)了,我當(dāng)時(shí)就懵逼了,這簡(jiǎn)直是歷史的倒退啊。

后來(lái)我接受了html5,因?yàn)槲伊私饬怂悄敲疵?,語(yǔ)意標(biāo)簽,不再?gòu)?qiáng)迫開(kāi)發(fā)者,慢慢理解了html5的思想,接受現(xiàn)實(shí),因?yàn)闉g覽器就是這么做的,xhtml的理想在現(xiàn)實(shí)面前無(wú)法落地,散落了一地悲傷。

再后來(lái)whatwg將html5改為html,并標(biāo)榜為活著的語(yǔ)言,還是因?yàn)闉g覽器就是這么做的,我也激動(dòng)了,web本該如此,早怎么沒(méi)想到呢。

知道最近w3c說(shuō)要發(fā)布html5.1了,雖然html沒(méi)有了版本的概念,但是w3c必須要整理出版本來(lái),不然后面想做html解析器的人估計(jì)就懵逼了。

說(shuō)完了html再來(lái)說(shuō)說(shuō)css,如下:

  • css2.1
  • css3
  • css module

開(kāi)始接觸的也是css2.1,感覺(jué)這個(gè)東西挺簡(jiǎn)單啊,但簡(jiǎn)直就是高大上啊,比c語(yǔ)言那個(gè)黑窗口厲害多了,我要學(xué)會(huì)全部的選擇器,全部的屬性,后來(lái)我真的做到了,每一個(gè)屬性都如數(shù)家珍,橫掃了圖書(shū)館每一本書(shū)籍。

再后來(lái)css3來(lái)了,我心里說(shuō)真是什么鬼,css已經(jīng)夠用了,請(qǐng)不要再添加垃圾,雖然我極力反對(duì),但我無(wú)能為力,沒(méi)有人能聽(tīng)到我的吶喊,我除了接受什么都做不了,好吧我又被強(qiáng)奸了,但還高潮了,我愛(ài)上了css3,簡(jiǎn)直棒棒的,我也曾想過(guò)全部掌握每一個(gè)屬性,后來(lái)發(fā)現(xiàn)my god,臣妾做不到啊。

再后來(lái)在知乎上被@winter老師點(diǎn)醒,css3其實(shí)也是不存在的,css2.1之后css就拆分了,因?yàn)樗罅耍仨毑鸱?,就想html是一樣的。

說(shuō)完了css再來(lái)說(shuō)說(shuō)js,如下:

  • js
  • es3
  • es5
  • es6
  • es*

歷史的發(fā)展總是相似的,上面的經(jīng)歷,注定我的js入門(mén)也是悲劇的,先學(xué)js,后來(lái)學(xué)es3,再后來(lái)es5來(lái)了,我也是抵制的,js已經(jīng)夠用了,請(qǐng)不要再添加了,我的嗓子都嘶啞了,你們能不能聽(tīng)聽(tīng)我的呼聲,開(kāi)發(fā)規(guī)范的老古董能不能考慮考慮開(kāi)發(fā)者的聲音呢。

結(jié)果可想而知,我又愛(ài)上了es5,知道去年es6來(lái)了,真是日了狗了,class,proxies,generators,reflect輕饒了js吧,給js一條生路號(hào)碼,js不需要這些垃圾的東西,這是java程序員才需要的狗屎。

結(jié)果嗎當(dāng)然就是今天這篇文章啦,我愛(ài)上了es6,并且我想推薦給你,讓你也愛(ài)上。

再來(lái)說(shuō)說(shuō)我的瀏覽器,如下:

  • ie6
  • ie7
  • ie8
  • firefox
  • opera
  • chrome

說(shuō)起來(lái)可能是悲劇,但我最開(kāi)始開(kāi)發(fā)用的瀏覽器竟然是ie6,后來(lái)基本在倒騰ie 6 7 8,可能我入門(mén)就選擇最難用的瀏覽器(對(duì)開(kāi)發(fā)來(lái)說(shuō)),后來(lái)改用firefox,感覺(jué)這個(gè)加上firebug簡(jiǎn)直就是神器。

再后來(lái)很崇拜opera,因?yàn)槲腋杏X(jué)這款瀏覽器簡(jiǎn)單,好用,后來(lái)有了chrome我就放棄了其他瀏覽器了,這個(gè)簡(jiǎn)直就是開(kāi)發(fā),生活全好用啊,特別是翻墻后就是無(wú)敵了。

相關(guān)鏈接:

最后來(lái)說(shuō)說(shuō)編輯器之旅,工欲善其事必先利其器,一個(gè)程序員必須有一個(gè)好的編輯器,雖然熟能生巧,但你用notepad和sublime比都不在同一個(gè)級(jí)別里,你再怎么熟料也是比不過(guò)人家的,我的編輯器之旅如下:

  • notepad
  • frontpage
  • dreamweaver
  • aptana
  • sublime

從notepad一路走來(lái),說(shuō)多了都是淚,現(xiàn)在我推薦大家用sublime。

從寫(xiě)代碼,到所見(jiàn)即所得,再到繼續(xù)寫(xiě)代碼,編輯器也在跟著換,目前sublime是我最喜歡的編輯器了,因?yàn)槲蚁矚g他的速度。

相關(guān)鏈接:

歷史

以史為鑒可以明得失 —— 李世民 溫故而知新可以為師矣 —— 孔子 學(xué)而不思則罔思而不學(xué)則殆 —— 孔子

古人早就告訴我們歷史的重要性,鑒于很多同學(xué)其實(shí)不太清楚js的歷史,所在在開(kāi)始學(xué)習(xí)新知識(shí)之前我們先來(lái)連接下js的歷史。

網(wǎng)景

提到j(luò)s的歷史不得不提網(wǎng)景公司,有興趣的同學(xué)可以自行查閱資料。

這家公司開(kāi)發(fā)了一個(gè)牛逼的軟件,就是網(wǎng)景瀏覽器,網(wǎng)景瀏覽器風(fēng)靡一時(shí),成為了人們通往因特網(wǎng)的唯一入口,后來(lái)為了給瀏覽器擴(kuò)展本地驗(yàn)證表的等的功能,于是乎創(chuàng)造了javascript。

Mozilla

后來(lái)在和IE的競(jìng)爭(zhēng)中失敗了,雖然失敗了,但是還是很有錢(qián)和技術(shù),于是乎成立了Mozilla基金會(huì)。

Mozilla決定將自己的瀏覽器開(kāi)源,于是乎有了firefox,火狐瀏覽器憑借出色的用戶體驗(yàn)和豐富而插件,以及開(kāi)源終于臥薪嘗膽,改變了IE一家獨(dú)大的局面,才有了后面的chrome橫空出世,從而形成今天三分天下的局面。

Mozilla帶給我們web開(kāi)發(fā)者最大禮物除了firefox還有開(kāi)發(fā)者社區(qū)MDN,我現(xiàn)在經(jīng)常在上面查閱自己不知道的知識(shí)。

相關(guān)鏈接:

JS之父

Brendan Eich花了10天時(shí)間設(shè)計(jì)了javascript,借鑒了c的語(yǔ)法,函數(shù)借鑒了scheme,原型借鑒了self。

相關(guān)鏈接:

JS進(jìn)化史

下面的一張圖其實(shí)完美呈現(xiàn)了javascript的進(jìn)化史。

開(kāi)始時(shí)js其實(shí)叫做livescript,當(dāng)時(shí)java正火,便打上了java的順飛車(chē),改名叫做javascript,開(kāi)始時(shí)一直伴隨Netscape發(fā)布,后來(lái)ie也加入進(jìn)了戰(zhàn)爭(zhēng),并開(kāi)發(fā)了自己的JScript,網(wǎng)景便去ECMA提交了自己的語(yǔ)言,從此ECMA負(fù)責(zé)制定js語(yǔ)言的標(biāo)準(zhǔn),因?yàn)閯偤檬堑?62號(hào)標(biāo)準(zhǔn),所以變叫做 ecma-262,因?yàn)閖ava的版權(quán)在java的公司sun手里面,所指便ecma便給自己的規(guī)范改名為ecmascript,下文簡(jiǎn)稱ES。

1999年制定了ES3的規(guī)范,將近10年時(shí)間語(yǔ)言層面沒(méi)有大的改動(dòng),知道08年結(jié)尾,籌劃了10年之久的ES4被廢棄了,而是推出了更少改動(dòng),更友好的的ES5。

2011年對(duì)ES5進(jìn)修了一次修訂,一直到2015年6月份,ES6的規(guī)發(fā)布了,并規(guī)定以后的ES規(guī)范以年份命名,每年發(fā)布一個(gè)小版本,再不會(huì)像ES6這種一下發(fā)布很多功能了。

下圖是我從網(wǎng)上找到的一個(gè)關(guān)于重大事情發(fā)生的關(guān)鍵時(shí)間點(diǎn)的圖,可以來(lái)看一下。

相關(guān)鏈接:

ES&JS

需要區(qū)分ES(ECMAScript)和JS(JavaScript)的區(qū)別,我們常說(shuō)的js可能包括es+宿主環(huán)境,當(dāng)然有時(shí)候js也可指代es,sun只把js的名稱使用權(quán)限售給了Mozilla。一般說(shuō)es指代規(guī)范,js指代具體的實(shí)現(xiàn)。

方言

其實(shí)除了JS外還有一些其他的ES方言,比較出名的ActionScript 3,除此之外還有一些,比如:QtScript 和DMDScript等(我都沒(méi)聽(tīng)過(guò),囧)。其實(shí)如果可以的話你自己也可以按照規(guī)范寫(xiě)一個(gè)ES的方言。

TC39

推進(jìn) JavaScript 發(fā)展的委員會(huì)

  • 會(huì)員都是公司
  • 定期召開(kāi)會(huì)議
  • 會(huì)議由會(huì)員公司的代表與特邀專家出席

TC39 實(shí)行的是協(xié)商一致的原則:通過(guò)一項(xiàng)決議必須得到每一位會(huì)員(公司代表)的贊成

下圖是TC39的一些會(huì)員和其在github上的TC39 team的公開(kāi)成員。

TC39流程

TC39的工作流程其實(shí)也可用下面一張圖來(lái)總結(jié):

ECMA262 狀態(tài)

可以在這里查看目前處于各個(gè)狀態(tài)的ecmascript未來(lái)版本的特性。其中stage1-4分別對(duì)應(yīng)相面的1-4。

問(wèn)題

最后拋給大家一個(gè)問(wèn)題,這個(gè)問(wèn)題沒(méi)有答案,需要大家自己思考,就是TC39這種方式的優(yōu)缺點(diǎn),一個(gè)語(yǔ)言有一個(gè)團(tuán)隊(duì)制定規(guī)范和個(gè)人開(kāi)發(fā)者制定規(guī)范的優(yōu)缺點(diǎn),可以參考xhtml2.0之死。

新特性

有哪些

我想初次了解ES6的人,一定會(huì)懵逼的,就像看到下面的圖片一樣,我勒個(gè)去了,這都是什么,其實(shí)ES6改動(dòng)之多簡(jiǎn)直不亞于重新設(shè)計(jì)了一門(mén)語(yǔ)言,不說(shuō)新增的新特性,可以說(shuō)是原有的幾乎每一項(xiàng)都有所修改,改動(dòng)點(diǎn)不下于數(shù)百個(gè)之多。

面對(duì)如此之多的新特性,那么我們從何入手呢?改如何學(xué)起?

相關(guān)鏈接:

ES規(guī)范

其實(shí)根據(jù)80 20原則,我們可以知道,這么多特性中常用的可能只有20%,就像之前的js,其中的精粹部分也只有100多頁(yè)。

其實(shí)ES6中有很多特型都是為node而生,實(shí)際上這其中我們能夠在平時(shí)常用到的,并且好用的可能也就是20%不到,所以大家不要有那么多恐懼。

模塊系統(tǒng)

我們最先介紹的是模塊系統(tǒng),因?yàn)槟K系統(tǒng)是社區(qū)做的最多探索的一塊,也誕生了很多很多私有的模塊系統(tǒng),我在我的博文《JavaScript模塊的前世今生》中有過(guò)一些闡述。

常見(jiàn)的模塊系統(tǒng)有下面這些:

  • AMD
  • CMD
  • commonjs
  • UMD
  • 。。。

如果你一個(gè)也不知道那么也沒(méi)關(guān)系,因?yàn)閺慕裉扉_(kāi)始你就不需要這些,因?yàn)镋S6為我們帶來(lái)了全新的模塊系統(tǒng)。

ES6模塊系統(tǒng)的特性:

  • 靜態(tài)模塊(模塊名不能是變量)
  • 聲明式語(yǔ)法

可以像下面這樣引入模塊:

import {$} from 'jquery.js'; // es6

var $ = require('jquery.js')['$']; // amd

像下面這樣導(dǎo)出模塊:

export {$}; // es6

export.$ = $; // amd

注意:從這里開(kāi)始,負(fù)責(zé)任的我在每一個(gè)ES6代碼下面都寫(xiě)上了對(duì)等的ES5實(shí)現(xiàn)方法 注意:從這里開(kāi)始,負(fù)責(zé)任的我在每一個(gè)ES6代碼下面都寫(xiě)上了對(duì)等的ES5實(shí)現(xiàn)方法 注意:從這里開(kāi)始,負(fù)責(zé)任的我在每一個(gè)ES6代碼下面都寫(xiě)上了對(duì)等的ES5實(shí)現(xiàn)方法

ES6模塊系統(tǒng)和AMD相比有一些不一樣的思想,總結(jié)一下就是:

  • 按需引入 vs 全局引入
  • 多點(diǎn)暴漏 vs 全局暴漏

模塊思想代碼解釋:

import {each, ...} from 'underscore.js'; // es6

var _ = require('underscore.js'); // amd


export {each, map, ...}; // es6

module.exports = _; // amd

需要注意的是目前還沒(méi)有任何一款瀏覽器支持ES6模塊系統(tǒng),這主要是因?yàn)镋S規(guī)范僅僅定義了一套引入和導(dǎo)出的規(guī)范,而沒(méi)有定義具體如何實(shí)現(xiàn),其實(shí)現(xiàn)方式在瀏覽器端和node端都有很多大爭(zhēng)議,在ES7以及未來(lái)的規(guī)范中很可能解決這個(gè)問(wèn)題,目前社區(qū)也在做積極的探索。詳細(xì)內(nèi)容可以參考這篇文章《為何 ES Module 如此姍姍來(lái)遲》。

所以目前為止我們想使用ES6的模塊系統(tǒng)可以有兩種方案:

  • SystemJS
  • transpiler(轉(zhuǎn)換器),如ES6 module transpiler,babel,Traceur

推薦特性

所以我們今天并不打算介紹每一個(gè)特型,不然這篇文章就寫(xiě)不完了,如果你想了解ES6的方方面面可以查看下面的參考鏈接,這里只會(huì)介紹我在之前文章中總結(jié)的我個(gè)人認(rèn)為對(duì)于前端比較適合的特性。

  • 字符串
  • 解構(gòu)賦值
  • 對(duì)象
  • 數(shù)組
  • 函數(shù)
  • Class
  • Promise

相關(guān)鏈接:

字符串

ES6對(duì)字符串做了擴(kuò)展,引入了一種新的字符串,可以支持字符串插值和多行字符串。

// 字符串
`yanhaijing ${abc}`; // es6

'yanhaijing' + abc;

`yanhaijing
.
com`; // es6

'yanhaijing' +
'.' +
'com'; // es5

其中字符串插值還可配合模版一起使用,同時(shí)現(xiàn)在支持全部Unicode碼了,另外還增加了一組字符串接口,感興趣的同學(xué)可以深入了解,個(gè)人感覺(jué)比較實(shí)用的就是字符串插值和多行字符串了。

解構(gòu)

ES6帶來(lái)了解構(gòu)的功能,解構(gòu)支持下面的一些場(chǎng)景:

  • 數(shù)組解構(gòu)
  • 對(duì)象解構(gòu)
  • 字符串結(jié)構(gòu)
  • 數(shù)值和布爾值的解構(gòu)賦值
  • 函數(shù)參數(shù)的解構(gòu)賦值

代碼:

// 解構(gòu)
var arr = [1, 2, 3, 4];

var [first, second] = arr; // es6

var first = arr[0]; // es5
var second = arr[1]; // es5

var obj = {a: 1, b: 2};

var {a, b} = obj; // es6

var a = obj.a; // es5
var b = obj.b; // es5

function add([x, y]){
    return x + y;
}

add([1, 2]) // 3

關(guān)于解構(gòu)還有一些其他的黑魔法,感興趣的同學(xué)可自行了解。

對(duì)象

ES6對(duì)對(duì)象字面量進(jìn)行了擴(kuò)展,支持屬性同名變量簡(jiǎn)寫(xiě),屬性名求值,屬性為函數(shù)的簡(jiǎn)寫(xiě)等:

// 對(duì)象
var a = 1;
var obj = {
    a,
    [a + 1]: 3,
    add() {}
} // es6

obj[a+1] = 3; // es5

同時(shí)ES6還擴(kuò)展了一批對(duì)象的接口,感興趣的同學(xué)可自行了解。

Spread

Spread是數(shù)組的一個(gè)新功能,可以快速實(shí)現(xiàn)數(shù)組的拷貝,需要注意的是這里是對(duì)直接子元素的淺拷貝。

// 數(shù)組
var arr1 = [1, 2, 3];
var arr2 = [...arr1]; //es6 淺拷貝

var arr2 = [].concat(arr1); // es5
var arr2 = arr1.slice(0);

min(...arr2); 

函數(shù)

ES6的函數(shù)也帶來(lái)了很多新特性,這里主要介紹下面三點(diǎn):

  • 箭頭函數(shù)
  • rest參數(shù)
  • 默認(rèn)值

先來(lái)說(shuō)說(shuō)箭頭函數(shù)吧,這個(gè)是為lamada表達(dá)式而生,個(gè)人感覺(jué)和數(shù)組方法結(jié)合起來(lái)特別好用。

// 箭頭函數(shù)
[1, 2, 3].map(x => x + 1); // es6

[1, 2, 3].map(function(x) {
        return x + 1;
}.bind(this)); // es5

[1, 2, 3].filter(x => {return x > 2});

(x, y, z) => {***}

注意:箭頭函數(shù)中的this是綁定的。

再來(lái)說(shuō)說(shuō)rest參數(shù),在之前可以通過(guò)arguments參數(shù)來(lái)模擬rest參數(shù),但現(xiàn)在有了真正的rest參數(shù)了。

rest必須放在最后,代表后面的傳入?yún)?shù),其是一個(gè)真正的數(shù)組。

// rest參數(shù)
function aaa(...args) {
        return args.join(',');
} // es6

function aaa() {
        return [].slice.call(arguments, 0).join(',');
} // es5

function bbb(x, y, ...args) {

}

bbb(1, 2, ...[3, 4, 5]); // 和數(shù)組的spread結(jié)合起來(lái)簡(jiǎn)直完美

再來(lái)說(shuō)說(shuō)函數(shù)參數(shù)的默認(rèn)值吧,有了這個(gè)就省了不少事了。

// 默認(rèn)值
function f(a = 1) {} // es6

function f(a) {
        a = typeof a === 'undefined' ? 1: a; // es5
}

Class

ES6之前想要模擬一個(gè)class真是費(fèi)了牛勁了,我們一般通過(guò)new 構(gòu)造函數(shù)的方式來(lái)模擬,社區(qū)也是有很多種方法,光學(xué)會(huì)這些方法都得花費(fèi)很多精力。

class典型的特色如下:

  • 公有共享屬性/方法
  • 公有靜態(tài)屬性/方法
  • 公有特權(quán)方法(訪問(wèn)私有成員)
  • 公有成員
  • 私有靜態(tài)成員/方法
  • 私有成員/方法

現(xiàn)在ES6為我們帶來(lái)了原生的class,終于讓世界重歸一統(tǒng)。

// class
class Child extends Parent {
    constructor() {
        super();
        this.value = 1;
    }
    get() {
        return this.value;
    }
}

關(guān)于這個(gè)問(wèn)題我之前還寫(xiě)過(guò)兩篇文章可以參考:

Promise

Promise的典型狀態(tài)如下,這里不做過(guò)多介紹,如果你感興趣可以看我的這篇文章《快來(lái)使用ES2015的Promise吧》。

關(guān)于Promise我想說(shuō)的就是思想的轉(zhuǎn)變,以前我們是傳入一個(gè)回調(diào)函數(shù),現(xiàn)在返回給我們一個(gè)將來(lái)會(huì)改變的值。

Promise的兼容性目前還有很大問(wèn)題,所以必須使用pollyfill庫(kù),具體可以查看我上面介紹的文章。

我們一般像下面這樣使用Promise

// Promise
function async() {
    return new Promise((resolve, reject) => {
        window.setTimeout(() => {resolve(123);}, 1000);
    });
}

async().then(function() {
    // xxx
});

對(duì)應(yīng)的回調(diào)函數(shù)代碼如下:

// es5
function async(cb) {
    window.setTimeout(function() {
        cb();
    }, 1000);
}

async(function() {
    // ***
})

一個(gè)典型的回調(diào)地獄的例子如下:

function delay(time, cb) {
    window.setTimeout(function() {cb()}, time);
}

delay(100, function() {
    delay(200, function() {
        delay(300, function() {
            delay(400, function() {
                delay(500, function() {
                    delay(600, function() {
                        delay(700, function() {
                            delay(800, function() {
                                console.log('yanhaijing.com');
                            })
                        })
                    })
                })
            })
        })
    })
});

用Promise后的典型代碼如下:

function delay(time) {
    return new Promise(function (resolve, reject) {
        window.setTimeout(function() {resolve()}, time);
    });
}

delay(100).then(function() {
    return delay(200);
}).then(function() {
    return delay(300);
}).then(function() {
    return delay(400);
}).then(function() {
    return delay(500);
}).then(function() {
    return delay(600);
}).then(function() {
    return delay(700);
}).then(function() {
    return delay(800);
}).then(function() {
    console.log('yanhaijing.com');
});

一個(gè)常見(jiàn)的誤區(qū)我們不要像下面這樣使用Promise:

delay(100).then(function() {
    delay(200).then(function() {
        delay(300).then(function() {
            delay(400).then(function() {
                delay(500).then(function() {
                    delay(600).then(function() {
                        delay(700).then(function() {
                            delay(800).then(function() {
                                console.log('yanhaijing.com');
                            })
                        })
                    })
                })
            })
        })
    })
});

關(guān)于Promise的更多誤區(qū)我們可以查看這篇文章《We have a problem with promises》。

相關(guān)鏈接:

其他

這里還有很多其他新特性我們沒(méi)有介紹到,如果你感興趣可以自行了解,文章結(jié)尾的相關(guān)資料是個(gè)不錯(cuò)的參考:

  • generators
  • unicode
  • module loaders
  • map + set + weakmap + weakset
  • proxies
  • symbols
  • subclassable built-ins
  • math + number + string + array + object APIs
  • binary and octal literals
  • reflect api
  • tail calls

實(shí)戰(zhàn)

ES5

先來(lái)看看ES5目前的兼容性,從下圖看兼容性還是很好的。

兼容性

再來(lái)看看ES6的兼容性,簡(jiǎn)直慘不忍睹啊。

我為什么支持/抵制ES6

作為一個(gè)來(lái)自ES3時(shí)代的老古董,堅(jiān)決反對(duì)ES4,經(jīng)歷并擁護(hù)ES5的變革的我,起初我對(duì)ES6是抵制的,對(duì)ES6是抵制的,對(duì)ES6是抵制的。

ES6在搞什么鬼,竟然不能向后兼容,這簡(jiǎn)直違背Web的設(shè)計(jì)理念,HTML,css都是向后兼容的,你竟然不向后兼容,對(duì)不起我不能使用你。滾,滾,滾。。。

編譯器/轉(zhuǎn)換器/編碼器

其實(shí)直到我了解了編譯器,才轉(zhuǎn)變了我的想法,并開(kāi)始支持和使用ES6。

編譯器的靈感其實(shí)其實(shí)并不是憑空而生的,想coffeescript/typescript中早就開(kāi)始使用了,我們可以把ES5比喻成匯編語(yǔ)言(目標(biāo)語(yǔ)言),而降ES5+比喻成C語(yǔ)言(源語(yǔ)言),從而完成下面的轉(zhuǎn)換。

這是一場(chǎng)思想的轉(zhuǎn)變,ES5 是Web時(shí)代的匯編語(yǔ)言,編譯不可避免。

無(wú)處不在的編譯器

其實(shí)對(duì)于編譯器,我們?cè)缇烷_(kāi)始使用了,不信你看下面的列表,你肯定使用過(guò)其中一個(gè)呢。

  • masm
  • gcc
  • javac
  • coffeescript/typescript
  • less/sass

轉(zhuǎn)換器

那么將我們的ES6轉(zhuǎn)換成ES5的轉(zhuǎn)換器有哪些呢?其實(shí)也是有不少的,比如:

  • babel
  • Traceur(google)

Babel

我要給大家分享的就Babel,通過(guò)babel我們?cè)诮裉炀涂梢允褂肊S6,甚至是ES7。

Babel是一個(gè)杰出的編譯器,前身是大名鼎鼎的6to5,后來(lái)為了順應(yīng)未來(lái)ES7,便改名為babel,不再局限于6to5。

Babel 5vs6

Babel最近推出了v6版本,關(guān)于版本的選擇也是個(gè)藝術(shù)問(wèn)題,我一般是推薦選擇最新版的。

6相對(duì)于5最大的變化就是擁抱ES*,每個(gè)ES屬性都是一個(gè)插件,而不是像之前那樣都揉在了一起,我們可以自由拼裝自己想要的特性,自由組合,每個(gè)團(tuán)隊(duì)都可以有自己的的選擇權(quán)。

但目前6在npm2的架構(gòu)下,安裝起來(lái)太大了,而且問(wèn)題也是蠻多的,我們可以坐等其成成熟了再來(lái)使用,現(xiàn)在可以先選擇相對(duì)穩(wěn)定的5.x,當(dāng)然如果是嘗鮮的話還是推薦6的,這個(gè)版本一旦選擇了,以后就要謹(jǐn)慎更新,最好是寫(xiě)死不要更新。

如何使用

Babel提供了一個(gè)在線的編譯器,方便大家上手體驗(yàn),感興趣的同學(xué)請(qǐng)猛戳這里。

真正到項(xiàng)目中我們還是得解構(gòu)構(gòu)建工具來(lái)使用,Babel提供了各種構(gòu)建工具的使用方法,可以查看這里

下面我們主要介紹如何在fis中使用babel。

fis插件

如果你不了解fis可以先猛戳這里進(jìn)行了解,簡(jiǎn)單說(shuō)就是一個(gè)前端集成構(gòu)建工具,在fis中我們想使用babel,需要用到下面兩個(gè)插件:

fis配置

配置這個(gè)簡(jiǎn)單了,你想用哪個(gè)插件都寫(xiě)得很清楚了,這里就不展開(kāi)了。

兼容老代碼

我們遇到最大的一個(gè)問(wèn)題就是歷史代碼絕對(duì)不能用babel編譯,不然可能各種報(bào)錯(cuò),這里提供兩種解決這個(gè)問(wèn)題的思路:

  • .es
  • .es.js

可以將需要編譯的代碼后綴名設(shè)置為.es,或者.es.js,或者自定義的xxx.js。

推薦規(guī)范

我推薦大家使用babel-5.x這個(gè)插件,并且將需要編譯的后綴名設(shè)置為.es。

這里唯一的一個(gè)缺點(diǎn)就是.es會(huì)繞過(guò)百度代碼檢查,這可能是一把雙刃劍,長(zhǎng)期來(lái)說(shuō)不利于代碼質(zhì)量。

優(yōu)點(diǎn)

先來(lái)說(shuō)說(shuō)Babel的優(yōu)點(diǎn),Babel可以讓我們現(xiàn)在就是用ES6,如果等著瀏覽器都支持恐怕要到2020年了,甚至現(xiàn)在就能讓我們使用ESnext中的一些特性。

缺點(diǎn)

Babel的缺點(diǎn)也是顯而易見(jiàn)的,比如需要引入編譯流程,對(duì)于沒(méi)有構(gòu)建工具的團(tuán)隊(duì)是一大挑戰(zhàn),對(duì)于已經(jīng)邁入前端工程化的團(tuán)隊(duì)也會(huì)帶來(lái)額外的編譯時(shí)間。

同時(shí)線上代碼的排錯(cuò)問(wèn)題也變得更難了,因?yàn)榫€上都是編譯后的代碼,雖然sourcemap能一定程度上解決這個(gè)問(wèn)題。

Babel作為一個(gè)編譯工具,其自身的問(wèn)題也是不容忽略的,5升級(jí)6都是有風(fēng)險(xiǎn)的,起穩(wěn)定性和兼容性是最大的問(wèn)題,遠(yuǎn)沒(méi)有g(shù)cc這種工具穩(wěn)定得多。前段時(shí)間發(fā)生的left-pad事件對(duì)于我們的功能都是有威脅的。

Babel的局限性也是個(gè)問(wèn)題,Babel只能解決語(yǔ)法層面的問(wèn)題,api相關(guān)的還是需要shim來(lái)解決,還有一些是Babel和shim都不能解決的,我們只能坐等瀏覽器更新了,好消息是現(xiàn)在瀏覽器更新速度越來(lái)越快了,O(∩_∩)O哈哈~

廣告1

終于來(lái)到我喜歡的廣告時(shí)間了,如果你想體驗(yàn)es6,而又自己懶得搭環(huán)境,那么沒(méi)關(guān)系我都給你搭好了,你可以適用我的fis3-base,拿來(lái)即用的fis3腳手架。

廣告2

如果你原來(lái)適用baidutemplate,那么用了es6后,你一定會(huì)郁悶的,因?yàn)閑s6會(huì)全部是嚴(yán)格模式,而baidutemplate在嚴(yán)格模式下報(bào)錯(cuò),我推薦你用我的template.js,和baidutemplate 100%兼容,同時(shí)支持嚴(yán)格模式。

你可能踩過(guò)的坑,我都踩過(guò)啦,O(∩_∩)O哈哈~

未來(lái)

未來(lái)已經(jīng)到來(lái)。

更多ES規(guī)范

TC39和瀏覽器廠商現(xiàn)在打成了一致,會(huì)加快規(guī)范的發(fā)布速度,再也不會(huì)出現(xiàn)以前10年一個(gè)版本的問(wèn)題,以后每年一個(gè)版本,ES7會(huì)在今年發(fā)布,ES8會(huì)在明年發(fā)布,每年的夏天6月份都會(huì)發(fā)布新的規(guī)范,同時(shí)規(guī)范將會(huì)以年份命名,比如今年夏天將會(huì)發(fā)布ES2016,會(huì)帶來(lái)乘方運(yùn)算符等新特性。

以后每個(gè)新版規(guī)范帶來(lái)的特性都會(huì)變得更少,再也不會(huì)出現(xiàn)ES6這種一下這么多新特性的規(guī)范了,歷史終將遠(yuǎn)去,并不會(huì)再次上演。

精粹

現(xiàn)在的 迫切希望能有個(gè)ES6語(yǔ)言精粹,因?yàn)槲移珗?zhí)的認(rèn)為,新特性一定也有糟粕,坐等了,如果沒(méi)人動(dòng)手,我可能會(huì)嘗試來(lái)做這個(gè)事情。

我還想要的是ES的前端子集,ES6有太多東西都是為了Node而生的,并不適合前端,這對(duì)于前端工程師學(xué)習(xí)成本還是蠻大的,我希望大家都能用最少的精力,做更多的事情,而不是恰恰相反,特別是對(duì)于團(tuán)隊(duì)內(nèi)部的普及,這將起到事半功倍的效果,今天的這篇文章中提到的部分,可能就是我認(rèn)為的精粹和前端子集部分。

瀏覽器

目前主流的瀏覽器有chrome,firefox,ie,safari,現(xiàn)在的瀏覽器廠商已經(jīng)達(dá)成一致,沒(méi)6周會(huì)發(fā)布一個(gè)版本,ie6 10年一個(gè)版本的時(shí)代再也不會(huì)有了,ie團(tuán)隊(duì)更是激進(jìn)每4周會(huì)發(fā)一個(gè)大版本。

這讓我看到了js無(wú)限的潛能,感覺(jué)有些無(wú)限演進(jìn)的意思,這個(gè)平臺(tái)的活力真正還是爆發(fā)了。

我們?cè)趺醋?/h3>

首先需要說(shuō)明下,我們特指前端FE,babel必不可少,我們可以定制自己的babel插件,然后等那個(gè)屬性沒(méi)有兼容性問(wèn)題了就刪掉這個(gè)插件。

未來(lái)已經(jīng)到來(lái),我們應(yīng)該面向未來(lái)。

總結(jié)

堅(jiān)持看到這里的同學(xué),我想先給你們一個(gè)鼓勵(lì),你們真是棒棒的,我想大家此刻的腦子里可能下下面這幅畫(huà)一樣,暈暈的,亂亂的,下面我們就來(lái)做個(gè)總結(jié),幫你理理思路。

優(yōu)點(diǎn)

ES6的優(yōu)點(diǎn)非常明顯,總結(jié)起來(lái)大概有如下:

  • 官方規(guī)范,趨勢(shì),面向未來(lái),未來(lái)會(huì)原生支持
  • 代碼變現(xiàn)力更強(qiáng)了,代碼行數(shù)更少
  • 同時(shí)開(kāi)發(fā)效率大大提升
  • 減少對(duì)第三方庫(kù)的依賴,比如underscore,promise等

缺點(diǎn)

ES6沒(méi)有缺點(diǎn)嗎?沒(méi)有,但是還是可以總結(jié)出來(lái)一些:

  • ES6很多特性面向node.js,對(duì)前端無(wú)用
  • 需要我們學(xué)習(xí)新東西,對(duì)某些人可能是挑戰(zhàn)
  • js變得更復(fù)雜了,新人生手難度更大
  • 這么多東西糟粕在所難免,需要去取精華

收益

借用babel在線編輯器提供的例子來(lái)看一下收益,實(shí)現(xiàn)同樣邏輯功能的代碼ES6是100行,而ES5卻要200行,這收益簡(jiǎn)直就是100%啊。

然而我們實(shí)際測(cè)試發(fā)現(xiàn)并沒(méi)有這么完美,實(shí)際中大概能節(jié)省30%左右的代碼量(工作量)。

其次更少的意味著邏輯更清晰,可維護(hù)性更好,一個(gè)人能完成的工作量也就更多了,哈哈。

開(kāi)發(fā)時(shí)間可以大幅減少,開(kāi)發(fā)消息大大提升。

為什么

下面我們來(lái)說(shuō)說(shuō)為什么要學(xué)習(xí)ES6,我想能看到這里的同學(xué)多半是有興趣的,所以我給大家解惑一下,大概可以有一下幾點(diǎn):

  • 遲早要學(xué)(區(qū)別ts,cs),因?yàn)槭且?guī)范,所以你遲早要學(xué)的,被動(dòng)不如主動(dòng),晚學(xué)不如早學(xué),規(guī)范即標(biāo)準(zhǔn),你遲早要學(xué)
  • 社區(qū)的趨勢(shì),和你團(tuán)隊(duì)的趨勢(shì)都會(huì)想規(guī)范靠攏,目前的瀏覽器也是如此,大趨勢(shì)不可違背
  • ES6的表現(xiàn)力更強(qiáng),這往往意味著可維護(hù)性更高
  • 學(xué)習(xí)成本很小,相信我只要你用心3天足夠了,塌下心來(lái)嘗試一下吧
  • 編程激情,如果你有黑客精神,那么你應(yīng)該學(xué)習(xí),相信我ES6重新燃起了我編程的激情
  • 如果你也不想加班,那么你該學(xué)習(xí)ES6,他會(huì)讓你寫(xiě)代碼變得更快
  • 面試中的加分項(xiàng),如果你想在出去面試,ES6會(huì)成為你的加分項(xiàng)

做出選擇

下圖出自黑客帝國(guó),neo需要做出選擇,是回到dream world,還是real world,關(guān)鍵是選擇,但關(guān)鍵的關(guān)鍵是做出選擇,用于不用就看你了。

參考資料

相關(guān)資料

問(wèn)答

悲催的是沒(méi)有一個(gè)人提問(wèn),╮(╯▽╰)╭,連我的托都聽(tīng)懵逼了。。。

彩蛋

一般來(lái)說(shuō)到這里就該結(jié)束了,但作為一個(gè)負(fù)責(zé)人的步道師,我還是給大家準(zhǔn)備了彩蛋。

值得關(guān)注的項(xiàng)目

我的一些開(kāi)源庫(kù)

我寫(xiě)的小游戲

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)