感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大獎(jiǎng):點(diǎn)擊這里領(lǐng)取
這個(gè)系列叢書到底是為了什么?簡(jiǎn)單地說,它的目的是認(rèn)真地學(xué)習(xí) JavaScript的所有部分,不僅是這門語言的某些人稱之為“好的部分”的子集,也不僅是讓你在工作中搞定任務(wù)所需的最小部分的知識(shí)。
其他語言中,認(rèn)真的開發(fā)者總是希望努力學(xué)習(xí)他們主要使用的語言的大部分或全部,但是JS開發(fā)者由于通常不太學(xué)習(xí)這門語言而在人群中顯得很扎眼。這不是一件好事,而且我們也不應(yīng)當(dāng)繼續(xù)將之視為常態(tài)。
你不懂JS(YDKJS)系列的立場(chǎng)是與學(xué)習(xí)JS的通常方式形成鮮明的對(duì)比,而且與你將會(huì)讀到的其他JS書籍不同。它挑戰(zhàn)你超越自己的舒適區(qū),對(duì)每一個(gè)你遇到的行為問一個(gè)更深入的“為什么”。你準(zhǔn)備好接受挑戰(zhàn)了嗎?
我將用這最后一章的篇幅來簡(jiǎn)要地總結(jié)一下這個(gè)系列其他書目的內(nèi)容,和如何在 YDKJS 的基礎(chǔ)上最有效地建立學(xué)習(xí)JS的基礎(chǔ)。
作用域與閉包
也許你需要快速接受的基礎(chǔ)之一,就是在JavaScript中變量的作用域是如何工作的。關(guān)于作用域僅有傳聞中的模糊 觀念 是不夠的。
作用域與閉包 從揭穿常見的誤解開始:JS是“解釋型語言”因此是不被編譯的。不對(duì)。
JS引擎在你的代碼執(zhí)行的前一刻(有時(shí)是在執(zhí)行期間!)編譯它。所以我們首先深入了解編譯器處理我們代碼的方式,以此來理解它如何找到并處理變量和函數(shù)的聲明。沿著這條道路,我們將見到JS變量作用域管理的特有隱喻,“提升”。
對(duì)“詞法作用域”的極其重要的理解,是我們?cè)谶@本書最后一章探索閉包時(shí)所需的基石。閉包也許是JS所有的概念中最重要的一個(gè),但如果你沒有首先牢牢把握住作用域的工作方式,那么閉包將很可能依然不在你的掌握之中。
閉包的一個(gè)重要應(yīng)用是模塊模式,正如我們?cè)诒緯诙轮泻?jiǎn)要介紹過的那樣。模塊模式也許是JavaScript的所有代碼組織模式中最流行的一種;深刻理解它應(yīng)當(dāng)是你的首要任務(wù)之一。
this與對(duì)象原型
也許關(guān)于JavaScript傳播得最廣泛和持久的謬誤之一是認(rèn)為this
關(guān)鍵字指代它所出現(xiàn)的函數(shù)。可怕的錯(cuò)誤。
this
關(guān)鍵字是根據(jù)函數(shù)如何被執(zhí)行而動(dòng)態(tài)綁定的,而事實(shí)上有四種簡(jiǎn)單的規(guī)則可以用來理解和完全決定this
綁定。
和this
密切相關(guān)的是對(duì)象原型屬性,它是一種屬性的查詢鏈,與查詢?cè)~法作用域變量的方式相似。但是原型中包含的是另一個(gè)關(guān)于JS的巨大謬誤:模擬(山寨)類和繼承(所謂的“原型繼承”)的想法。
不幸的是,渴望將類和繼承的設(shè)計(jì)模式思想帶入JavaScript只是你能做的最差勁兒的事情,因?yàn)殡m然語法可能欺騙你,使你認(rèn)為有類這樣的東西存在,但實(shí)際上原型機(jī)制在行為上是根本相反的。
目前的問題是,是忽略這種錯(cuò)位并假裝你實(shí)現(xiàn)的是“繼承”更好,還是學(xué)習(xí)并接納對(duì)象原型系統(tǒng)實(shí)際的工作方式更恰當(dāng)。后者被稱為“行為委托”更合適。
這不光是語法上的偏好問題。委托是一種完全不同的,更強(qiáng)大的設(shè)計(jì)模式,其中的原因之一就是它取代了使用類和繼承進(jìn)行設(shè)計(jì)的需要。但是對(duì)于以談?wù)揓avaScript的一生為主題的幾乎所有的其他博客,書籍,和論壇來說,這些斷言絕對(duì)是打臉的。
我對(duì)委托和繼承做出的宣言不是源于對(duì)語言和其語法的厭惡,而是來自于渴望看到這門語言的真實(shí)力量被正確地利用,渴望看到無盡的困惑與沮喪被一掃而光。
但是我舉出的關(guān)于原型和委托的例子可要比我在這里亂說的東西復(fù)雜得多。如果你準(zhǔn)備好重新思考你認(rèn)為你所了解的關(guān)于JavaScript“類”和“繼承”的一切,我給你一個(gè)機(jī)會(huì)來“服用紅色的藥丸”,并且看一看本系列的 this與對(duì)象原型 的第四到六章。
類型與文法
這個(gè)系列的第三本書主要集中于解決另一個(gè)極具爭(zhēng)議的話題:類型強(qiáng)制轉(zhuǎn)換。也許沒有什么話題能比你談?wù)撾[含的強(qiáng)制轉(zhuǎn)換造成的困惑更能使JS開發(fā)者感到沮喪了。
到目前為止,慣例的智慧說隱含強(qiáng)制轉(zhuǎn)換是這門語言的“壞的部分”,并且應(yīng)當(dāng)不計(jì)一切避免它。事實(shí)上,有些人已經(jīng)到了將它稱為語言設(shè)計(jì)的“缺陷”的地步了。確實(shí)存在這么一些工具,它們的全部工作就是掃描你的代碼,并在你進(jìn)行任何強(qiáng)制轉(zhuǎn)換,甚至是做有些像強(qiáng)制轉(zhuǎn)換的事情時(shí)報(bào)警。
但是強(qiáng)制轉(zhuǎn)換真的如此令人困惑,如此的壞,如此的不可信,以至于只要你使用它,你的代碼從一開始就滅亡了嗎?
我說不。在第一到三章中建立了對(duì)類型和值真正的工作方式的理解后,第四章參與了這個(gè)辯論,并從強(qiáng)制轉(zhuǎn)換的角落和縫隙全面地講解它的工作方式。我們將看到強(qiáng)制轉(zhuǎn)換的哪一部分真的令人驚訝,而且如果花時(shí)間去學(xué)習(xí),哪一部分實(shí)際上完全是合理的。
但我不僅僅要說強(qiáng)制轉(zhuǎn)換是合理的和可以學(xué)習(xí)的,我斷言強(qiáng)制轉(zhuǎn)換是一種 你應(yīng)當(dāng)在代碼中使用的 極其有用而且完全被低估的工具。我要說在合理使用的情況下,強(qiáng)制轉(zhuǎn)換不僅可以工作,而且會(huì)使你的代碼更好。所有唱反調(diào)的和懷疑的人當(dāng)然會(huì)嘲笑這樣的立場(chǎng),但我相信它是讓你玩兒好JS游戲的主要按鍵之一。
你是想繼續(xù)人云亦云,還是想將所有的臆測(cè)放在一邊,用一個(gè)全新的視角觀察強(qiáng)制轉(zhuǎn)換?這個(gè)系列的 類型與文法 將會(huì)強(qiáng)制轉(zhuǎn)換你的想法。
異步與性能
這個(gè)系列的前三本書聚焦于這門語言的核心技術(shù),但是第四本書稍稍開出一個(gè)分支來探討在這門語言技術(shù)之上的管理異步編程的模式。異步不僅對(duì)于性能和我們的應(yīng)用程序很關(guān)鍵,而且它日漸成為改進(jìn)可寫性和可維護(hù)性的關(guān)鍵因素。
這本書從搞清楚許多令人困惑的術(shù)語和概念開始,比如“異步”,“并行”和“并發(fā)”。而且深入講解了這些東西如何適用和不適用于JS。
然后我們繼續(xù)檢視作為開啟異步的主要方法:回調(diào)。但我們很快就會(huì)看到,對(duì)于現(xiàn)代異步編程的需求來說,單靠回調(diào)自身是遠(yuǎn)遠(yuǎn)不夠的。我們將找出僅使用回調(diào)編碼的兩種主要的不足之處:控制反轉(zhuǎn)(IoC)信任丟失和缺乏線性的可推理性。
為了解決這兩種主要的不足,ES6引入了兩種新的機(jī)制(實(shí)際上也是模式):promise 和 generator。
Prmise是一個(gè)“未來值”的一種與時(shí)間無關(guān)的包裝,它讓你推理并組合這些未來值而不必關(guān)心它們是否已經(jīng)準(zhǔn)備好。另外,它們通過將回調(diào)沿著一個(gè)可信賴和可組裝的promise機(jī)制傳遞,有效地解決了IoC信任問題。
Generator給JS函數(shù)引入了一種新的執(zhí)行模式,generator可以在yield
點(diǎn)被暫停而稍后異步地被繼續(xù)。這種“暫停-繼續(xù)”的能力讓generator在幕后異步地被處理,使看起來同步,順序執(zhí)行的代碼成為可能。如此,我們就解決了回調(diào)的非線性,非本地跳轉(zhuǎn)的困惑,并因此使我們的異步代碼看起來是更容易推理的同步代碼。
但是,是promise與generator的組合給了我們JavaScript中最有效的異步代碼模式。事實(shí)上,在即將到來的ES7與之后的版本中,大多數(shù)精巧的異步性肯定會(huì)建立在這個(gè)基礎(chǔ)之上。為了認(rèn)真地在一個(gè)異步的世界中高效地編程,你將需要對(duì)promise與generator的組合十分適應(yīng)。
如果promise和generator是關(guān)于表達(dá)一些模式,這些模式讓你的程序更加并發(fā)地運(yùn)行,而因此在更短的時(shí)間內(nèi)完成更多的處理,那么JS在性能優(yōu)化上就擁有許多其他的方面值得探索。
第五章鉆研的話題是使用Web Worker的程序并行性和使用SIMD的數(shù)據(jù)并行性,以及像ASM.js這樣的底層優(yōu)化技術(shù)。第六章從正確的基準(zhǔn)分析技術(shù)的角度來觀察性能優(yōu)化,包括什么樣的性能值得關(guān)心而什么應(yīng)當(dāng)忽略。
高效地編寫JavaScript意味著編寫的代碼可以突破這種限制壁壘:在范圍廣泛的瀏覽器和其他環(huán)境中動(dòng)態(tài)運(yùn)行。這需要我們進(jìn)行更多復(fù)雜的詳細(xì)計(jì)劃與努力,才能使一個(gè)程序從“可以工作”到“工作得很好”。
給你編寫合理且高效的JavaScript代碼所需的全部工具與技能,異步與性能 就是為此而設(shè)計(jì)的。
ES6與未來
至此,無論你感覺自己已經(jīng)將JavaScript掌握的多么好,現(xiàn)實(shí)是JavaScript從來沒有停止過進(jìn)化,而且進(jìn)化的頻率正在飛快地增長(zhǎng)。這個(gè)事實(shí)幾乎就是本系列精神的含義,擁抱我們永遠(yuǎn)不會(huì)完全 懂得 的JS的所有部分,因?yàn)橹灰阏莆樟怂娜浚蜁?huì)有你需要學(xué)習(xí)的新的東西到來。
這本書專注于這門語言在中短期的發(fā)展前景,不僅是像ES6這樣 已知的 東西,還包括在未來 可能的 東西。
雖然這個(gè)系列的所有書目采納的是在編寫它們時(shí)JavaScript的狀態(tài),也就是ES6正在被接納的半途中,但是這個(gè)系列更主要地集中于ES5。現(xiàn)在我們想要將注意力轉(zhuǎn)移到ES6,ES7,和……
因?yàn)樵诰帉懕緯鴷r(shí)ES6已經(jīng)近于完成,ES6與未來 首先將ES6中確定的東西分割為幾個(gè)關(guān)鍵的范疇,包括新的語法,新的數(shù)據(jù)結(jié)構(gòu)(集合),和新的處理能力以及API。我們將在各種細(xì)節(jié)的層面講解這些新的ES6特性中的每一個(gè),包括復(fù)習(xí)我們?cè)诒鞠盗械钠渌麜恐杏龅竭^的細(xì)節(jié)。
這是一些值得一讀的激動(dòng)人心的ES6特性:解構(gòu),參數(shù)默認(rèn)值,symbol,簡(jiǎn)潔方法,計(jì)算屬性,箭頭函數(shù),塊兒作用域,promise,generator,iterator,模塊,代理,weakmap,以及很多,很多別的東西!呼,ES6真是不容小覷!
這本書的第一部分是一張路線圖,為了對(duì)你將要在以后幾年中編寫和探索的新改進(jìn)的JavaScript做好準(zhǔn)備,它指明了你需要學(xué)習(xí)的所有東西。
這本書稍后的部分將注意力轉(zhuǎn)向簡(jiǎn)要地介紹一些我們將在近未來可能看到的JavaScript的新東西。在這里最重要的是,要理解在后ES6時(shí)代,JS很可能將會(huì)一個(gè)特性一個(gè)特性地進(jìn)化,而不是一個(gè)版本一個(gè)版本地進(jìn)化,這意味著我們將在比你想象的早得多的時(shí)候,看到這些近未來的到來。
JavaScript的未來是光明的。這不正是我們開始學(xué)習(xí)它好時(shí)機(jī)嗎!?
復(fù)習(xí)
YDKJS 系列投身于這樣的命題:所有的JS開發(fā)者都可以,也應(yīng)該學(xué)習(xí)這門偉大語言的每一部分。沒有任何個(gè)人意見,沒有任何框架的設(shè)想,沒有任何項(xiàng)目的期限可以作為你從沒有學(xué)習(xí)和深入理解JavaScript的借口。
我們聚焦這門語言中的每一個(gè)重要領(lǐng)域,為之專著一本很短但是內(nèi)容非常稠密的書,來全面地探索它的 —— 你也許認(rèn)為自己知道但可能并不全面 —— 所有部分。
“你不懂JS”不是一種批評(píng)或羞辱。它是我們所有人,包括我自己,都必須正視的一種現(xiàn)實(shí)。學(xué)習(xí)JavaScript不是一個(gè)最終目標(biāo),而是一個(gè)過程。我們還不懂JavaScript。但是我們會(huì)的!