成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

精讀《你不知道的javascript(中卷)》

李世贊 / 3149人閱讀

摘要:強(qiáng)制類型轉(zhuǎn)換本章介紹了的數(shù)據(jù)類型之間的轉(zhuǎn)換即強(qiáng)制類型轉(zhuǎn)換包括顯式和隱式。強(qiáng)制類型轉(zhuǎn)換常常為人詬病但實(shí)際上很多時候它們是非常有用的。隱式強(qiáng)制類型轉(zhuǎn)換則沒有那么明顯是其他操作的副作用。在處理強(qiáng)制類型轉(zhuǎn)換的時候要十分小心尤其是隱式強(qiáng)制類型轉(zhuǎn)換。

前言

《你不知道的 javascript》是一個前端學(xué)習(xí)必讀的系列,讓不求甚解的JavaScript開發(fā)者迎難而上,深入語言內(nèi)部,弄清楚JavaScript每一個零部件的用途。本書《你不知道的javascript》中卷介紹了該系列的兩個主題:“類型和語法”以及“異步與性能”。這兩塊也是值得我們反復(fù)去學(xué)習(xí)琢磨的兩塊只是內(nèi)容,今天我們用思維導(dǎo)圖的方式來精讀一遍。(思維導(dǎo)圖圖片可能有點(diǎn)小,記得點(diǎn)開看,你會有所收獲)

第一部分 作用域和閉包 類型


JavaScript 有 七 種 內(nèi) 置 類 型: null 、 undefined 、 boolean 、 number 、 string 、 object 和 symbol ,可以使用 typeof 運(yùn)算符來查看。

變量沒有類型,但它們持有的值有類型。類型定義了值的行為特征。

很 多 開 發(fā) 人 員 將 undefined 和 undeclared 混 為 一 談, 但 在 JavaScript 中 它 們 是 兩 碼 事。 undefined 是值的一種。 undeclared 則表示變量還沒有被聲明過。

遺憾的是, JavaScript 卻將它們混為一談, 在我們試圖訪問 "undeclared" 變量時這樣報(bào) 錯:ReferenceError: a is not defined, 并 且 typeof 對 undefined 和 undeclared 變 量 都 返 回 "undefined" 。

然而,通過 typeof 的安全防范機(jī)制(阻止報(bào)錯)來檢查 undeclared 變量,有時是個不錯的辦法。


JavaScript 中的數(shù)組是通過數(shù)字索引的一組任意類型的值。字符串和數(shù)組類似,但是它們的 行為特征不同, 在將字符作為數(shù)組來處理時需要特別小心。 JavaScript 中的數(shù)字包括“整 數(shù)”和“浮點(diǎn)型”。

基本類型中定義了幾個特殊的值。

null 類型只有一個值 null , undefined 類型也只有一個值 undefined 。 所有變量在賦值之 前默認(rèn)值都是 undefined 。 void 運(yùn)算符返回 undefined 。

數(shù) 字 類 型 有 幾 個 特 殊 值, 包 括 NaN ( 意 指“not a number” , 更 確 切 地 說 是“invalid number” )、 +Infinity 、 -Infinity 和 -0 。

簡單標(biāo)量基本類型值(字符串和數(shù)字等)通過值復(fù)制來賦值 / 傳遞, 而復(fù)合值(對象等) 通過引用復(fù)制來賦值 / 傳遞。 JavaScript 中的引用和其他語言中的引用 / 指針不同,它們不 能指向別的變量 / 引用,只能指向值。

原生函數(shù)

JavaScript

為基本數(shù)據(jù)類型值提供了封裝對象,稱為原生函數(shù)(如 String 、 Number 、 Boolean 等)。它們?yōu)榛緮?shù)據(jù)類型值提供了該子類型所特有的方法和屬性(如: String#trim() 和 Array#concat(..) )。

對于簡單標(biāo)量基本類型值,比如 "abc" ,如果要訪問它的 length 屬性或 String.prototype 方法, JavaScript 引擎會自動對該值進(jìn)行封裝(即用相應(yīng)類型的封裝對象來包裝它)來實(shí)現(xiàn)對這些屬性和方法的訪問。

強(qiáng)制類型轉(zhuǎn)換

本章介紹了 JavaScript 的數(shù)據(jù)類型之間的轉(zhuǎn)換,即強(qiáng)制類型轉(zhuǎn)換:包括顯式和隱式。

強(qiáng)制類型轉(zhuǎn)換常常為人詬病, 但實(shí)際上很多時候它們是非常有用的。 作為有使命感的 JavaScript 開發(fā)人員,我們有必要深入了解強(qiáng)制類型轉(zhuǎn)換,這樣就能取其精華,去其糟粕。

顯式強(qiáng)制類型轉(zhuǎn)換明確告訴我們哪里發(fā)生了類型轉(zhuǎn)換, 有助于提高代碼可讀性和可維 護(hù)性。

隱式強(qiáng)制類型轉(zhuǎn)換則沒有那么明顯,是其他操作的副作用。感覺上好像是顯式強(qiáng)制類型轉(zhuǎn) 換的反面,實(shí)際上隱式強(qiáng)制類型轉(zhuǎn)換也有助于提高代碼的可讀性。

在處理強(qiáng)制類型轉(zhuǎn)換的時候要十分小心,尤其是隱式強(qiáng)制類型轉(zhuǎn)換。在編碼的時候,要知 其然,還要知其所以然,并努力讓代碼清晰易讀。

語法


JavaScript 語法規(guī)則中的許多細(xì)節(jié)需要我們多花點(diǎn)時間和精力來了解。 從長遠(yuǎn)來看, 這有 助于更深入地掌握這門語言。

語句和表達(dá)式在英語中都能找到類比——語句就像英語中的句子,而表達(dá)式就像短語。表 達(dá)式可以是簡多帶帶立的,否則可能會產(chǎn)生副作用。

JavaScript 語法規(guī)則之上是語義規(guī)則(也稱作上下文)。例如, { } 在不同情況下的意思不 盡相同,可以是語句塊、對象常量、解構(gòu)賦值(ES6)或者命名函數(shù)參數(shù)(ES6)。

JavaScript 詳細(xì)定義了運(yùn)算符的優(yōu)先級(運(yùn)算符執(zhí)行的先后順序)和關(guān)聯(lián)(多個運(yùn)算符的 組合方式)。只要熟練掌握了這些規(guī)則,就能對如何合理地運(yùn)用它們作出自己的判斷。

ASI(自動分號插入)是 JavaScript 引擎的代碼解析糾錯機(jī)制, 它會在需要的地方自動插 入分號來糾正解析錯誤。問題在于這是否意味著大多數(shù)的分號都不是必要的(可以省略), 或者由于分號缺失導(dǎo)致的錯誤是否都可以交給 JavaScript 引擎來處理。

JavaScript 中有很多錯誤類型, 分為兩大類:早期錯誤(編譯時錯誤, 無法被捕獲)和運(yùn) 行時錯誤(可以通過 try..catch 來捕獲)。所有語法錯誤都是早期錯誤,程序有語法錯誤 則無法運(yùn)行。

函數(shù)參數(shù)和命名參數(shù)之間的關(guān)系非常微妙。尤其是 arguments 數(shù)組,它的抽象泄漏給我們 挖了不少坑。因此,盡量不要使用 arguments ,如果非用不可,也切勿同時使用 arguments 和其對應(yīng)的命名參數(shù)。

finally 中代碼的處理順序需要特別注意。它們有時能派上很大用場,但也容易引起困惑, 特別是在和帶標(biāo)簽的代碼塊混用時。總之,使用 finally 旨在讓代碼更加簡潔易讀,切忌 弄巧成拙。

switch 相對于 if..else if.. 來說更為簡潔。需要注意的一點(diǎn)是,如果對其理解得不夠透 徹,稍不注意就很容易出錯。

第二部分 this 和對象原型 異步:現(xiàn)在與將來


實(shí)際上, JavaScript 程序總是至少分為兩個塊:第一塊 現(xiàn)在 運(yùn)行;下一塊 將來 運(yùn)行, 以響 應(yīng)某個事件。盡管程序是一塊一塊執(zhí)行的,但是所有這些塊共享對程序作用域和狀態(tài)的訪 問,所以對狀態(tài)的修改都是在之前累積的修改之上進(jìn)行的。

一旦有事件需要運(yùn)行, 事件循環(huán)就會運(yùn)行, 直到隊(duì)列清空。 事件循環(huán)的每一輪稱為一個 tick。 用戶交互、IO 和定時器會向事件隊(duì)列中加入事件。

任意時刻,一次只能從隊(duì)列中處理一個事件。執(zhí)行事件的時候,可能直接或間接地引發(fā)一 個或多個后續(xù)事件。

并發(fā)是指兩個或多個事件鏈隨時間發(fā)展交替執(zhí)行,以至于從更高的層次來看,就像是同時 在運(yùn)行(盡管在任意時刻只處理一個事件)。

通常需要對這些并發(fā)執(zhí)行的“進(jìn)程”(有別于操作系統(tǒng)中的進(jìn)程概念)進(jìn)行某種形式的交 互協(xié)調(diào),比如需要確保執(zhí)行順序或者需要防止競態(tài)出現(xiàn)。這些“進(jìn)程”也可以通過把自身 分割為更小的塊,以便其他“進(jìn)程”插入進(jìn)來。

回調(diào)

回調(diào)函數(shù)是 JavaScript 異步的基本單元。但是隨著 JavaScript 越來越成熟,對于異步編程領(lǐng)域的發(fā)展,回調(diào)已經(jīng)不夠用了。

第一,大腦對于事情的計(jì)劃方式是線性的、阻塞的、單線程的語義,但是回調(diào)表達(dá)異步流 程的方式是非線性的、非順序的,這使得正確推導(dǎo)這樣的代碼難度很大。難于理解的代碼 是壞代碼,會導(dǎo)致壞 bug。

我們需要一種更同步、更順序、更阻塞的的方式來表達(dá)異步,就像我們的大腦一樣。

第二,也是更重要的一點(diǎn),回調(diào)會受到控制反轉(zhuǎn)的影響,因?yàn)榛卣{(diào)暗中把控制權(quán)交給第三 方(通常是不受你控制的第三方工具!)來調(diào)用你代碼中的 continuation。 這種控制轉(zhuǎn)移導(dǎo) 致一系列麻煩的信任問題,比如回調(diào)被調(diào)用的次數(shù)是否會超出預(yù)期。

可以發(fā)明一些特定邏輯來解決這些信任問題,但是其難度高于應(yīng)有的水平,可能會產(chǎn)生更 笨重、更難維護(hù)的代碼,并且缺少足夠的保護(hù),其中的損害要直到你受到 bug 的影響才會 被發(fā)現(xiàn)。

我們需要一個通用的方案來解決這些信任問題。不管我們創(chuàng)建多少回調(diào),這一方案都應(yīng)可 以復(fù)用,且沒有重復(fù)代碼的開銷。

我們需要比回調(diào)更好的機(jī)制。到目前為止,回調(diào)提供了很好的服務(wù),但是未來的 JavaScript 需要更高級、功能更強(qiáng)大的異步模式。本書接下來的幾章會深入探討這些新型技術(shù)。

Promise

Promise 非常好,請使用。它們解決了我們因只用回調(diào)的代碼而備受困擾的控制反轉(zhuǎn)問題。

它們并沒有擯棄回調(diào),只是把回調(diào)的安排轉(zhuǎn)交給了一個位于我們和其他工具之間的可信任 的中介機(jī)制。

Promise 鏈也開始提供(盡管并不完美)以順序的方式表達(dá)異步流的一個更好的方法,這 有助于我們的大腦更好地計(jì)劃和維護(hù)異步 JavaScript 代碼。我們將在第 4 章看到針對這個 問題的一種更好的解決方案!

生成器


生成器是 ES6 的一個新的函數(shù)類型, 它并不像普通函數(shù)那樣總是運(yùn)行到結(jié)束。 取而代之 的是, 生成器可以在運(yùn)行當(dāng)中(完全保持其狀態(tài))暫停, 并且將來再從暫停的地方恢復(fù) 運(yùn)行。

這種交替的暫停和恢復(fù)是合作性的而不是搶占式的,這意味著生成器具有獨(dú)一無二的能力 來暫停自身,這是通過關(guān)鍵字 yield 實(shí)現(xiàn)的。不過,只有控制生成器的迭代器具有恢復(fù)生 成器的能力(通過 next(..) )。

yield / next(..) 這一對不只是一種控制機(jī)制,實(shí)際上也是一種雙向消息傳遞機(jī)制。 yield .. 表 達(dá)式本質(zhì)上是暫停下來等待某個值,接下來的 next(..) 調(diào)用會向被暫停的 yield 表達(dá)式傳回 一個值(或者是隱式的 undefined )。

在異步控制流程方面,生成器的關(guān)鍵優(yōu)點(diǎn)是:生成器內(nèi)部的代碼是以自然的同步 / 順序方 式表達(dá)任務(wù)的一系列步驟。其技巧在于,我們把可能的異步隱藏在了關(guān)鍵字 yield 的后面, 把異步移動到控制生成器的迭代器的代碼部分。

換句話說,生成器為異步代碼保持了順序、同步、阻塞的代碼模式,這使得大腦可以更自 然地追蹤代碼,解決了基于回調(diào)的異步的兩個關(guān)鍵缺陷之一。

程序性能

本部分的前四章都是基于這樣一個前提:異步編碼模式使我們能夠編寫更高效的代碼,通 常能夠帶來非常大的改進(jìn)。但是,異步特性只能讓你走這么遠(yuǎn),因?yàn)樗举|(zhì)上還是綁定在 一個單事件循環(huán)線程上。

因此,在這一章里,我們介紹了幾種能夠進(jìn)一步提高性能的程序級別的機(jī)制。

Web Worker 讓你可以在獨(dú)立的線程運(yùn)行一個 JavaScript 文件(即程序),使用異步事件在 線程之間傳遞消息。 它們非常適用于把長時間的或資源密集型的任務(wù)卸載到不同的線程 中,以提高主 UI 線程的響應(yīng)性。

SIMD 打算把 CPU 級的并行數(shù)學(xué)運(yùn)算映射到 JavaScript API, 以獲得高性能的數(shù)據(jù)并行運(yùn)算,比如在大數(shù)據(jù)集上的數(shù)字處理。

最后, asm.js 描述了 JavaScript 的一個很小的子集, 它避免了 JavaScript 難以優(yōu)化的部分 (比如垃圾收集和強(qiáng)制類型轉(zhuǎn)換),并且讓 JavaScript 引擎識別并通過激進(jìn)的優(yōu)化運(yùn)行這樣 的代碼??梢允止ぞ帉?asm.js, 但是會極端費(fèi)力且容易出錯,類似于手寫匯編語言(這也 是其名字的由來)。實(shí)際上, asm.js 也是高度優(yōu)化的程序語言交叉編譯的一個很好的目標(biāo), 比如 Emscripten 把 C/C++ 轉(zhuǎn)換成 JavaScript(https://github.com/kripken/em... 。

JavaScript 還有一些更加激進(jìn)的思路已經(jīng)進(jìn)入非常早期的討論, 盡管本章并沒有明確包含 這些內(nèi)容,比如近似的直接多線程功能(而不是藏在數(shù)據(jù)結(jié)構(gòu) API 后面)。不管這些最終 會不會實(shí)現(xiàn),還是我們將只能看到更多的并行特性偷偷加入 JavaScript, 但確實(shí)可以預(yù)見, 未來 JavaScript 在程序級別將獲得更加優(yōu)化的性能。

性能測試與調(diào)優(yōu)

對一段代碼進(jìn)行有效的性能測試,特別是與同樣代碼的另外一個選擇對比來看看哪種方案 更快,需要認(rèn)真注意細(xì)節(jié)。

與其打造你自己的統(tǒng)計(jì)有效的性能測試邏輯,不如直接使用 Benchmark.js 庫,它已經(jīng)為你 實(shí)現(xiàn)了這些。但是,編寫測試要小心,因?yàn)槲覀兒苋菀拙蜁?gòu)造一個看似有效實(shí)際卻有缺 陷的測試,即使是微小的差異也可能扭曲結(jié)果,使其完全不可靠。

從盡可能多的環(huán)境中得到盡可能多的測試結(jié)果以消除硬件/ 設(shè)備的偏差, 這一點(diǎn)很重要。 jsPerf.com 是很好的網(wǎng)站,用于眾包性能測試運(yùn)行。

遺憾的是,很多常用的性能測試執(zhí)迷于無關(guān)緊要的微觀性能細(xì)節(jié),比如 x++ 對比 ++x 。編 寫好的測試意味著理解如何關(guān)注大局, 比如關(guān)鍵路徑上的優(yōu)化以及避免落入類似不同的 JavaScript 實(shí)現(xiàn)細(xì)節(jié)這樣的陷阱中。

尾調(diào)用優(yōu)化是 ES6 要求的一種優(yōu)化方法。它使 JavaScript 中原本不可能的一些遞歸模式變 得實(shí)際。 TCO 允許一個函數(shù)在結(jié)尾處調(diào)用另外一個函數(shù)來執(zhí)行,不需要任何額外資源。這意味著,對遞歸算法來說,引擎不再需要限制棧深度。

擴(kuò)展

思維導(dǎo)圖能比較清晰的還原整本書的知識結(jié)構(gòu)體系,如果你還沒用看過這本書,可以按照這個思維導(dǎo)圖的思路快速預(yù)習(xí)一遍,提高學(xué)習(xí)效率。學(xué)習(xí)新事物總?cè)菀走z忘,我比較喜歡在看書的時候用思維導(dǎo)圖做些記錄,便于自己后期復(fù)習(xí),如果你已經(jīng)看過了這本書,也建議你收藏復(fù)習(xí)。如果你有神馬建議或則想法,歡迎留言或加我微信交流:646321933,備注技術(shù)交流

精讀《你不知道的javascript》上卷

精讀《深入淺出Node.js》

思維導(dǎo)圖下載地址

你不知道的 javascript(中卷)PDF 下載地址

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95554.html

相關(guān)文章

  • 如何機(jī)制地回答瀏覽器兼容性問題

    摘要:前言有過面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問的。來談?wù)劄g覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如何才是我們正確回答這個問題的姿勢呢。 前言 有過面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問的。來談?wù)劄g覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如...

    leanote 評論0 收藏0
  • 如何機(jī)制地回答瀏覽器兼容性問題

    摘要:前言有過面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問的。來談?wù)劄g覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如何才是我們正確回答這個問題的姿勢呢。 前言 有過面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問過瀏覽器兼容性的問題,對于面試官的問題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問的。來談?wù)劄g覽器兼容的問題吧,你對瀏覽器的兼容性有了解過嗎,那么如...

    Rindia 評論0 收藏0
  • 思維導(dǎo)圖—你不知道JavaScript中卷

    xmind地址 預(yù)覽 showImg(https://segmentfault.com/img/bVbfhBm?w=1525&h=3460);

    CastlePeaK 評論0 收藏0
  • 你不知道JavaScript中卷 第一、二章

    摘要:表達(dá)式?jīng)]有返回值,因此返回結(jié)果是。并不改變表達(dá)式的結(jié)果,只要讓表達(dá)式不返回值按慣例我們用來獲得這主要源自語言,當(dāng)然使用或其他表達(dá)式也是可以的。不是數(shù)字的數(shù)字如果數(shù)學(xué)運(yùn)算的操作數(shù)不是數(shù)字類型,就無法返回一個有效的數(shù)字,這種情況下返回值為。 這里的內(nèi)容是讀書筆記,僅供自己學(xué)習(xí)所用,有欠缺的地方歡迎留言提示。 第一部分 類型和語法 第1章 類型ECMAScript語言類型包括Undefin...

    levy9527 評論0 收藏0
  • 掌握 Javascript 類型轉(zhuǎn)換:從規(guī)則開始

    摘要:首先,為了掌握好類型轉(zhuǎn)換,我們要理解一個重要的抽象操作為什么說這是個抽象操作呢因?yàn)檫@是內(nèi)部才會使用的操作,我們不會顯示調(diào)用到。基本規(guī)則中的類型轉(zhuǎn)換總是返回基本類型值,如字符串?dāng)?shù)字和布爾值,不會返回對象和函數(shù)。 Javascript 里的類型轉(zhuǎn)換是一個你永遠(yuǎn)繞不開的話題,不管你是在面試中還是工作寫代碼,總會碰到這類問題和各種的坑,所以不學(xué)好這個那是不行滴。關(guān)于類型轉(zhuǎn)換我也看過不少的書和各...

    mikyou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<