摘要:最近剛剛看完了你不知道的上卷,對(duì)有了更進(jìn)一步的了解。你不知道的上卷由兩部分組成,第一部分是作用域和閉包,第二部分是和對(duì)象原型。附錄詞法這一章并沒(méi)有說(shuō)明機(jī)制,只是介紹了中的箭頭函數(shù)引入的行為詞法。第章混合對(duì)象類類理論類的機(jī)制類的繼承混入。
最近剛剛看完了《你不知道的 JavaScript》上卷,對(duì) JavaScript 有了更進(jìn)一步的了解。
《你不知道的 JavaScript》上卷由兩部分組成,第一部分是《作用域和閉包》,第二部分是《this 和對(duì)象原型》。下面我會(huì)按照簡(jiǎn)單介紹一下每一章的主要內(nèi)容及閱讀感受。
第一部分《作用域和閉包》
第 1 章 作用域是什么編譯原理:簡(jiǎn)單介紹分詞/詞法分析、解析/語(yǔ)法分析、代碼生成的概念;
理解作用域:介紹引擎、編譯器、作用域之間的關(guān)系;
作用域嵌套。
在這一章節(jié)中,作者通過(guò)引擎、編譯器、作用域之間的對(duì)話,將這三者之間的關(guān)系及作用生動(dòng)形象地展現(xiàn)出來(lái),并引出了 LHS 查詢和 RHS 查詢的概念。
第 2 章 詞法作用域詞法作用域及其相關(guān)概念;
欺騙詞法的方式:
在代碼運(yùn)行時(shí)修改詞法作用域,如 eval();
在代碼運(yùn)行時(shí)創(chuàng)建新的詞法作用域,如 with。
這一章作者介紹了詞法作用域以及欺騙詞法的方式。說(shuō)來(lái)慚愧,在看這章之前,我完全沒(méi)聽(tīng)說(shuō)過(guò)「詞法作用域」這個(gè)概念,一開(kāi)始我還以為是個(gè)很高大上的東西,看完之后你會(huì)覺(jué)得其實(shí)也沒(méi)什么,就是你平時(shí)都在寫的東西,只不過(guò)你沒(méi)有留意而已。
第 3 章 函數(shù)作用域和塊作用域函數(shù)作用域:函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別、具名函數(shù)和匿名函數(shù);
塊作用域:with、try/catch、let、const。
這一章作者介紹了 JavaScript 中的函數(shù)作用域及塊作用域,講了函數(shù)聲明和函數(shù)表達(dá)式的區(qū)別,其實(shí)很簡(jiǎn)單,就是看 function 這個(gè)關(guān)鍵字是否是在聲明中的第一個(gè)詞,如果是,那就是函數(shù)聲明,否則就是函數(shù)表達(dá)式。另外,作者還簡(jiǎn)單地介紹了下 ES6 中具有塊作用域作用的 let 和 const 關(guān)鍵字。
在這之前,我一直以為 ES6 之前是沒(méi)有塊作用域的,只有全局作用域和函數(shù)作用域,看完這章之后,我才知道其實(shí)在 ES3 的時(shí)候就有塊作用域了。比如,with 。再比如,try/catch 中的 catch,一般我們是這樣寫的:
try { // do something } catch (err) { console.log(err) }
其中這個(gè) err 只存在 catch 分句內(nèi)部,從別處引用時(shí)會(huì)拋出錯(cuò)誤。這不就是塊作用域嗎?
第 4 章 提升這一章節(jié)作者簡(jiǎn)單地介紹了一下變量聲明提升和函數(shù)聲明提升。沒(méi)什么好說(shuō)的,需要注意的是函數(shù)表達(dá)式是賦值操作,并不會(huì)提升。
第 5 章 作用域閉包閉包;
作用域和閉包;
模塊機(jī)制。
閉包是 JavaScript 中的一大難點(diǎn),在這章中作者用了 4 個(gè)小節(jié)來(lái)介紹閉包,還有 1 個(gè)小節(jié)來(lái)介紹模塊機(jī)制。不要看閉包有四個(gè)小節(jié),其實(shí)也不過(guò) 8 頁(yè)而已,核心的文字加起來(lái)也就 2 頁(yè),但就是這短短的 2 頁(yè),就把閉包給講得非常清楚。
下面是書(shū)中給出關(guān)于閉包的定義:
當(dāng)函數(shù)可以記住并訪問(wèn)所在的詞法作用域時(shí),就產(chǎn)生了閉包,即使函數(shù)是在當(dāng)前詞法作用域之外執(zhí)行。
看了是不是還是不懂,沒(méi)關(guān)系,讓我們來(lái)提取關(guān)鍵字:
函數(shù);
記住并訪問(wèn)所在的詞法作用域;
當(dāng)前詞法作用域之外執(zhí)行。
再來(lái)看下書(shū)中的一段代碼,看完之后再結(jié)合書(shū)中的定義來(lái)理解,我相信你對(duì)閉包肯定會(huì)有更進(jìn)一步的理解。
function foo() { var a = 2; function bar() { console.log(a); } return bar; } var baz = foo(); baz(); // 2 —— 朋友,這就是閉包的效果。
下面結(jié)合我們剛剛提取的關(guān)鍵字來(lái)理解。
函數(shù)。這里的函數(shù)是 bar() ;
記住并訪問(wèn)。 bar() 當(dāng)前所在的詞法作用域是 foo() 的函數(shù)作用域。bar() 的詞法作用域能夠訪問(wèn) foo() 的內(nèi)部作用域。
當(dāng)前詞法作用域之外執(zhí)行。在上面的代碼中,我們將函數(shù) bar() 當(dāng)做一個(gè)值類型傳遞給外部,在這句代碼中 var baz = foo();,我們將 foo() 的返回值(也就是 bar())賦值給變量 baz 并調(diào)用 baz(),實(shí)際上就是調(diào)用 bar()。上面第 2 點(diǎn)里我們說(shuō)了,bar() 的作用域是 foo() 的函數(shù)作用域,但是,在這里,它卻是在自己定義的詞法作用域以外的地方執(zhí)行。
怎么樣,通過(guò)上面的分析,是不是對(duì)閉包有了進(jìn)一步的理解了。
附錄 A 動(dòng)態(tài)作用域作者在這一章中簡(jiǎn)單地分析了下動(dòng)態(tài)作用域,并通過(guò)一小段代碼將它與詞法作用域做了對(duì)比。詞法作用域與動(dòng)態(tài)作用域的主要區(qū)別在于:詞法作用域是在定義時(shí)確定的,而動(dòng)態(tài)作用域是在運(yùn)行時(shí)確定的。
附錄 B 塊作用域的替代方案這一章簡(jiǎn)單地介紹了塊作用域的替代方案 Traceur,以及因此可能會(huì)帶來(lái)的性能問(wèn)題。
附錄 C this 詞法這一章并沒(méi)有說(shuō)明 this 機(jī)制 ,只是介紹了 ES6 中的箭頭函數(shù)引入的行為 —— this 詞法。關(guān)于 this 機(jī)制的詳細(xì)說(shuō)明是在第二部分《this 和對(duì)象原型》中的第 1 章和 第 2 章。
附錄 D 致謝這一章作者致謝了一大堆的人,光人名的排版就占了兩頁(yè)多,說(shuō)真的,我都懷疑是不是在湊字?jǐn)?shù)了(純調(diào)侃,沒(méi)別的意思)。
第二部分《this 和對(duì)象原型》
第 1 章 關(guān)于 thisthis 的指向;
this 的作用域。
這一章中作者先是提出我們「為什么要使用 this?」這個(gè)問(wèn)題,然后再指出「this 到底是什么?」,為第 2 章做鋪墊。
這一章我個(gè)人認(rèn)為最核心的就是兩句話。第一句是「當(dāng)一個(gè)函數(shù)被調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(有時(shí)也稱為執(zhí)行上下文)。這個(gè)記錄會(huì)包含函數(shù)在哪里被調(diào)用(調(diào)用棧)、函數(shù)的調(diào)用方式、傳入的參數(shù)等信息。this 就是這個(gè)記錄的一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過(guò)程中用到」。也就是說(shuō),this 是活動(dòng)記錄里的一個(gè)屬性,與函數(shù)執(zhí)行的過(guò)程有關(guān)。
第二句話是「this 實(shí)際上是函數(shù)被調(diào)用時(shí)發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用?!?。第 2 章實(shí)際上就是在講這個(gè)綁定。
第 2 章 this 全面解析調(diào)用位置;
綁定規(guī)則:
默認(rèn)綁定;
隱式綁定;
顯式綁定:call()、apply()、bind();
new 綁定;
箭頭函數(shù)的綁定;
一些例外的綁定。
綁定規(guī)則的優(yōu)先級(jí)。
作者在這一章中全面介紹了 this 的綁定規(guī)則。
要弄清楚 this 的綁定對(duì)象,需要明白以下兩點(diǎn):
調(diào)用位置
綁定規(guī)則
什么是調(diào)用位置?簡(jiǎn)單來(lái)說(shuō),就是函數(shù)在代碼中被調(diào)用的位置。為了找到調(diào)用位置,我們需要分析調(diào)用棧,也就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù),而調(diào)用位置就在當(dāng)前正在執(zhí)行的函數(shù)的前一個(gè)調(diào)用中。
而綁定規(guī)則就是說(shuō) this 綁定的對(duì)象是有規(guī)則的,并且這些規(guī)則是有優(yōu)先級(jí)的,總的來(lái)說(shuō)有下面四點(diǎn):
由 new 調(diào)用的,綁定到新創(chuàng)建的對(duì)象;
由 call、apply、bind 調(diào)用的,綁定到指定的對(duì)象;
由上下文對(duì)象調(diào)用的,綁定到該上下文對(duì)象;
默認(rèn)的,在嚴(yán)格模式下綁定到 undefined,在非嚴(yán)格模式下綁定到全局對(duì)象。
當(dāng)然了,ES6 中新增的箭頭函數(shù)并不在這四條規(guī)則里面,而是繼承外層第一個(gè)非箭頭函數(shù)調(diào)用的 this 綁定。
在看這一章之前,我對(duì) this 一知半解,網(wǎng)上找的答案也是五花八門,根本不知道哪個(gè)對(duì)哪個(gè)錯(cuò)。在看完這一章之后,我算是對(duì) this 的所綁定的對(duì)象有了較為清晰的認(rèn)識(shí),以后再遇到類似的問(wèn)題時(shí),直接套用上面的規(guī)則就可以了。
第 3 章 對(duì)象JavaScript 中的數(shù)據(jù)類型;
內(nèi)置對(duì)象;
對(duì)象屬性與方法;
數(shù)組;
對(duì)象復(fù)制;
屬性描述符;
[[Get]] 操作與 [[Put]] 操作;
Getter 和 Setter;
遍歷及 ES6 中的 Symbol.iterator。
這一章講到了很多平時(shí)我并沒(méi)有注意到的東西,比如,一般來(lái)說(shuō),我們使用數(shù)組的時(shí)候都是下標(biāo)/值對(duì),但是,給數(shù)組添加屬性居然也是可以,雖然這并不會(huì)改變數(shù)組的長(zhǎng)度。當(dāng)我看到這一部分的內(nèi)容時(shí)心里在想:我去,這是什么騷操作?這樣居然也可以?后面想了想,數(shù)組其實(shí)也是對(duì)象,是一個(gè)特殊的對(duì)象,從這一方面來(lái)說(shuō)也是行得通的;再比如,屬性訪問(wèn)與賦值時(shí)發(fā)生的 [[Get]] 操作與 [[Put]] 操作,能夠更好地了解其工作原理;還有,我們可以利用 ES6 中的 Iterator 接口實(shí)現(xiàn)自己的迭代邏輯。
第 4 章 混合對(duì)象 “類”類理論;
類的機(jī)制;
類的繼承;
混入。
這一章講到了 “類” 這一設(shè)計(jì)模式,以及 JavaScript 中各種實(shí)現(xiàn)這一模式的方法。
這一章的核心就是:類的本質(zhì)是復(fù)制,多態(tài)和繼承也是。這一點(diǎn)很重要,JavaScript 中也有類,但是兩者的本質(zhì)是不同的,這一點(diǎn)在《第 5 章 原型》和《第 6 章 行為委托》里面有詳細(xì)的說(shuō)明。
這一章一開(kāi)始看的時(shí)候我是很模糊的,因?yàn)樽鳛橐幻?JavaScript 開(kāi)發(fā)者,說(shuō)實(shí)話我對(duì)于 “類” 這個(gè)東西的理解不是很明白,所以我跳過(guò)了這一章,等到看完了后面三章之后再回過(guò)來(lái)看,瞬間感覺(jué)清晰很多了。
第 5 章 原型[[Prototype]] 屬性;
屬性設(shè)置和屏蔽;
JavaScript 中的 “類”;
(原型)繼承;
對(duì)象關(guān)聯(lián)。
這一章中,第一小節(jié)的 [[Prototype]] 屬性可以和第 3 章中的 [[Put]] 操作結(jié)合一起看,這樣能夠完整的了解屬性賦值的工作原理;屬性設(shè)置和屏蔽這一部分可以和第 4 章結(jié)合著閱讀,以便更好地了解 JavaScript 中的類與其它語(yǔ)言中的類的區(qū)別。
第 6 章 行為委托這一章作者主要從類理論與委托理論(其實(shí)也就是對(duì)象關(guān)聯(lián))兩種不同的設(shè)計(jì)模式來(lái)介紹他們之間在代碼上實(shí)現(xiàn)的不同,可以看做是第 4 章和第 5 章的對(duì)象關(guān)聯(lián)的實(shí)踐部分。
附錄 A ES6 中的 Class這一章作者分析了 ES6 中新增的 Class 語(yǔ)法的優(yōu)點(diǎn)與缺點(diǎn)。
全書(shū)感悟
以上就是本書(shū)中的一些主要內(nèi)容介紹,我寫得比較簡(jiǎn)單,其實(shí)書(shū)中還有很多比較細(xì)小的東西,有興趣的同學(xué)可以去買來(lái)看看??偟膩?lái)說(shuō),這本書(shū)還是挺不錯(cuò)的,能讓你學(xué)到一些平時(shí)沒(méi)有注意到的東西,作者偏向于用口語(yǔ)化的文字來(lái)介紹知識(shí)點(diǎn),不會(huì)顯得枯燥。
最后,拋塊磚,希望能引塊玉。下面是我在閱讀本書(shū)過(guò)程中的做的思維導(dǎo)圖。導(dǎo)圖的內(nèi)容比較多,不是很簡(jiǎn)潔,因?yàn)槲蚁MM量把書(shū)中作者提到的概念提取出來(lái),所以可能會(huì)顯得比較啰嗦。
最后,歡迎關(guān)注我的微信公眾號(hào):前端路漫慢。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/108382.html
摘要:前言有過(guò)面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問(wèn)過(guò)瀏覽器兼容性的問(wèn)題,對(duì)于面試官的問(wèn)題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問(wèn)的。來(lái)談?wù)劄g覽器兼容的問(wèn)題吧,你對(duì)瀏覽器的兼容性有了解過(guò)嗎,那么如何才是我們正確回答這個(gè)問(wèn)題的姿勢(shì)呢。 前言 有過(guò)面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問(wèn)過(guò)瀏覽器兼容性的問(wèn)題,對(duì)于面試官的問(wèn)題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問(wèn)的。來(lái)談?wù)劄g覽器兼容的問(wèn)題吧,你對(duì)瀏覽器的兼容性有了解過(guò)嗎,那么如...
摘要:前言有過(guò)面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問(wèn)過(guò)瀏覽器兼容性的問(wèn)題,對(duì)于面試官的問(wèn)題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問(wèn)的。來(lái)談?wù)劄g覽器兼容的問(wèn)題吧,你對(duì)瀏覽器的兼容性有了解過(guò)嗎,那么如何才是我們正確回答這個(gè)問(wèn)題的姿勢(shì)呢。 前言 有過(guò)面試經(jīng)驗(yàn)的同學(xué)應(yīng)該都被問(wèn)過(guò)瀏覽器兼容性的問(wèn)題,對(duì)于面試官的問(wèn)題,常常猝不及防,因?yàn)橥ǔK麄兌际沁@么問(wèn)的。來(lái)談?wù)劄g覽器兼容的問(wèn)題吧,你對(duì)瀏覽器的兼容性有了解過(guò)嗎,那么如...
摘要:如果提升改變了代碼執(zhí)行的順序,會(huì)造成非常嚴(yán)重的破壞。聲明本身會(huì)被提升,而包括函數(shù)表達(dá)式的賦值在內(nèi)的賦值操作并不會(huì)提升。要注意避免重復(fù)聲明,特別是當(dāng)普通的聲明和函數(shù)聲明混合在一起的時(shí)候,否則會(huì)引起很多危險(xiǎn)的問(wèn)題 你不知道的JS(上卷)筆記 你不知道的 JavaScript JavaScript 既是一門充滿吸引力、簡(jiǎn)單易用的語(yǔ)言,又是一門具有許多復(fù)雜微妙技術(shù)的語(yǔ)言,即使是經(jīng)驗(yàn)豐富的 Ja...
摘要:的分句會(huì)創(chuàng)建一個(gè)塊作用域,其聲明的變量?jī)H在中有效。而閉包的神奇作用是阻止此事發(fā)生。依然持有對(duì)該作用域的引用,而這個(gè)引用就叫做閉包。當(dāng)然,無(wú)論使用何種方式對(duì)函數(shù)類型的值進(jìn)行傳遞,當(dāng)函數(shù)在別處被調(diào)用時(shí)都可以觀察到閉包。 date: 16.12.8 Thursday 第一章 作用域是什么 LHS:賦值操作的目標(biāo)是誰(shuí)? 比如: a = 2; RHS:誰(shuí)是賦值操作的源頭? 比如: conso...
摘要:遮蔽效應(yīng)作用域查找會(huì)在找到第一個(gè)匹配的標(biāo)識(shí)符時(shí)停止,不會(huì)繼續(xù)往上層作用域查找,這就會(huì)產(chǎn)生遮蔽效應(yīng)。會(huì)發(fā)現(xiàn)每一次輸出的都是為啥勒所有的回調(diào)函數(shù)回在循環(huán)結(jié)束后才會(huì)執(zhí)行事件循環(huán)。 三劍客 編譯,顧名思義,就是源代碼執(zhí)行前會(huì)經(jīng)歷的過(guò)程,分三個(gè)步驟, 分詞/詞法分析,將我們寫的代碼字符串分解成多個(gè)詞法單元 解析/語(yǔ)法分析,將詞法單元集合生成抽象語(yǔ)法樹(shù)(AST) 代碼生成,抽象語(yǔ)法樹(shù)(AST)轉(zhuǎn)...
閱讀 2554·2021-11-23 09:51
閱讀 598·2019-08-30 13:59
閱讀 1901·2019-08-29 11:20
閱讀 2583·2019-08-26 13:41
閱讀 3305·2019-08-26 12:16
閱讀 790·2019-08-26 10:59
閱讀 3399·2019-08-26 10:14
閱讀 657·2019-08-23 17:21