關於閉包

js語言的兩個核心技術-----------異步和閉包javascript

Question1:那麼什麼是閉包呢? 通俗的說法就是外層函數包裹內層函數,內層函數能夠調用外層函數的變量.............java

(這種解釋怎麼都感受有種自欺欺人的樣子,看來仍是須要進一步瞭解它的前世此生才能說,我理解撒是閉包)性能優化

----------------------------------------------------------------閉包

俗話說得好,他山之石能夠攻玉,有幾本書是如此來介紹閉包的:異步

NO1:閉包是指有權訪問另外一個函數做用域中的變量的函數(這個比較通俗易理解)函數

NO2:函數對象能夠經過做用域關聯起來,函數體內的變量均可以保存在函數做用域中,這在計算機科學文獻中稱爲'閉包',全部的javascript函數都是閉包性能

NO3:閉包是基於語法做用域書寫代碼時所產生的必然結果(提及來有點玄乎)優化

NO4:函數能夠經過做用域鏈關聯起來,函數內部的變量能夠保存在其它函數做用域內,這種特性在計算機科學文獻中稱爲閉包spa

----------------------------------------------------------------code

咱們從語法做用域做用域鏈的概念再到閉包的造成過程來梳理一下'閉包'

語法做用域

要理解語法做用域,咱們先來解釋JS的編譯階段,it goes without saying that JS is the weakly typed language, 所謂的弱類型是指不用預約義變量的存儲類型,不過這個弱類型不能徹底歸納JS和其它語言的區別,咱們這裏再來引出-----'編譯語言'(comes from<<你不知道的javascript>>)

編譯語言   

編譯語言在執行以前要經歷三個階段,這三個階段就像過濾器同樣,將咱們寫的代碼轉換成語言內部特定的可執行代碼,好比咱們寫的代碼是var a=1;而JS引擎內部定義的格式是 var,a,=,1 那在編譯階段 就須要把他們進行轉換.這只是一個比喻,而事實上這只是在編譯階段的第一個階段所作的事下面分析三個階段作了什麼. 

1.分詞/語法分析(Tokenizing/Lexing)

其實咱們寫的代碼就是字符串,在編譯的第一個階段,把這些字符串轉換成 語法單元(toekn), 語法單元咱們能夠想象成咱們上面分解的表達式那樣.(注意這個不步驟可能有兩種可能,當前這屬於 分詞,而 語法分析, 會在下面和語法做用域一塊兒說.)

2.解析/語法分析(Parsing)

在有了語法單詞以後,JS還須要繼續分析代碼中的語法以便JS引擎減少負擔(總不能在引擎運行的過程當中讓它承受這麼多輪的轉換規則吧?),經過語法單元生成了一個 抽象語法樹,(abstract syntax tree),它的做用是爲JS引擎構造出一份程序語法樹,咱們簡稱爲AST,這時咱們不由聯想到DOM 樹,他們都是樹,以 var,a,=,1爲例,它會以層爲單元劃分他們,例如:頂層有一個stepA裏面包含着'v',stepA下面有一個stepB,stepB中包含有'a',就這樣一層一層嵌套下去...

3.代碼生成(raw code)

這個階段主要作的就是拿AST來生成一份JS語言內部承認的 代碼(這時語言內部制定的,並非二進制),在生成的過程當中,編譯器還會詢問做用域的問題,仍是以var a=1爲例,編譯器首先會詢問做用域,當前有沒有變量a,若是有則忽略,不然在當前做用域下建立一個叫作a的變量

語法階段

   上面歸納的只是全部編譯語言最基本的流程,對於咱們的JS而言,它在編譯階段作的事情不單單是那些,它會提早爲js引擎作一些性能優化等工做,總之,編譯器乾的事情超乎你的想象.

   語法做用域是發生在編譯階段的第一個步驟當中,也就是分詞/詞法分析階段.它有兩種可能,分詞和語法分析,分詞是無狀態的,而語法分析是有狀態的.

---------------未完待續.....

相關文章
相關標籤/搜索