做用域 - note1(《你不知道的JavaScript》筆記,這個書寫的頗有趣,能夠看看)
程序var a = 2 處理時發生了啥
瞭解將要參與到對程序 var a = 2; 進行處理的過程當中的演員們。
- 引擎
- 從頭至尾負責整個 JavaScript 程序的編譯及執行過程。
- 編譯器
- 引擎的好朋友之一,負責語法分析及代碼生成等髒活累活。
- 做用域
- 引擎的另外一位好朋友,負責收集並維護由全部聲明的標識符(變量)組成的一系列查詢,並實施一套很是嚴格的規則,肯定當前執行的代碼對這些標識符的訪問權限。
在處理程序var a = 2這些演員具體幹了啥
- 遇到 var a,編譯器會詢問做用域是否已經有一個該名稱的變量存在於同一個做用域的 集合中。若是是,編譯器會忽略該聲明,繼續進行編譯;不然它會要求做用域在當前做 用域的集合中聲明一個新的變量,並命名爲 a。
- 接下來編譯器會爲引擎生成運行時所需的代碼,這些代碼被用來處理 a = 2 這個賦值 操做。引擎運行時會首先詢問做用域,在當前的做用域集合中是否存在一個叫做 a 的 變量。若是是,引擎就會使用這個變量;若是否,引擎會繼續查找該變量。若是引擎最終找到了 a 變量,就會將 2 賦值給它。不然引擎就會舉手示意並拋出一個異常。
瞭解引擎是如何進行查找的
瞭解LHS和RHS(你能夠理解成 retrieve his source value(取到它的源值),這意味着「獲得某某的 值」)
- 例子var a = 2,執行了LHS查詢,賦值操做經過LHS進行查詢。
- console.log(a), 變量a未進行賦值,則會經過RHS進行查詢a的值。
引擎如何在做用域的幫助下正確的查找
function foo(a) { console.log( a ); // 2
}
foo( 2 );
- 讓咱們把上面這段代碼的處理過程想象成一段對話,這段對話多是下面這樣的。
- 引擎:我說做用域,我須要爲 foo 進行 RHS 引用。你見過它嗎? 做用域:別說,我還真見過,編譯器那小子剛剛聲明瞭它。它是一個函數,給你。
- 引擎:哥們太夠意思了!好吧,我來執行一下 foo。 引擎:做用域,還有個事兒。我須要爲 a 進行 LHS 引用,這個你見過嗎? 做用域:這個也見過,編譯器最近把它聲名爲 foo 的一個形式參數了,拿去吧。
- 引擎:大恩不言謝,你老是這麼棒。如今我要把 2 賦值給 a。 引擎:哥們,很差意思又來打擾你。我要爲 console 進行 RHS 引用,你見過它嗎? 做用域:咱倆誰跟誰啊,再說我就是幹這個。這個我也有,console 是個內置對象。 給你。
- 引擎:麼麼噠。我得看看這裏面是否是有 log(..)。太好了,找到了,是一個函數。 引擎:哥們,能幫我再找一下對 a 的 RHS 引用嗎?雖然我記得它,但想再確認一次。 做用域:放心吧,這個變量沒有變更過,拿走,不謝。
- 引擎:真棒。我來把 a 的值,也就是 2,傳遞進 log(..)。