什麼是作用域
編譯原理
-
分詞/詞法分析
這個過程會將由字符組成的字符串分解成(對編程語言來說)有意義的代碼塊,這些代 碼塊被稱爲詞法單元(token)
-
解析/語法分析
這個過程是將詞法單元流(數組)轉換成一個由元素逐級嵌套所組成的代表了程序語法 結構的樹。這個樹被稱爲“抽象語法樹”(Abstract Syntax Tree,AST)。
什麼是抽象樹呢?在這個網站上可以在線的看到js源代碼,也就是抽象樹 在線生成抽象樹
-
代碼生成
將 AST 轉換爲可執行代碼的過程被稱爲代碼生成。
對於 JavaScript 來說,大部分情況下編譯發生在代碼執行前的幾微秒(甚至更短!)的時間內。 任何 JavaScript 代碼片段在執行前都要進行編譯(通常就在執行前)。 因此,JavaScript 編譯器首先會對 var a = 2; 這段程序進行編譯,然後做好執行它的準備,並且通常馬上就會執行它。
理解作用域
-
引擎
從頭到尾負責整個 JavaScript 程序的編譯及執行過程。
-
編譯器
引擎的好朋友之一,負責語法分析及代碼生成等髒活累活
-
作用域
引擎的另一位好朋友,負責收集並維護由所有聲明的標識符(變量)組成的一系列查 詢,並實施一套非常嚴格的規則,確定當前執行的代碼對這些標識符的訪問權限。
編譯器負責代碼生成,在生成的過程中會詢問作用域,例如變量是否聲明瞭。引擎整個編譯執行過程中也會詢問作用域 其中有LHS查詢和RHS查詢
對話(加強理解版)
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(..)。
聽我的,多看幾遍就能理解作用域跟LHS查詢 RHS查詢
作用域鏈
這是前端面試中經常會被問到的問題,這次我會想換一種方式回答這個問題。
作用域就好比是一棟大樓其中的一層,如果引擎詢問作用域查找某一個變量,他會先詢問(LHS和RHS)當前作用域,
如果當前作用域沒有就會往上詢問父級作用域,以此類推,直到最頂層(全局作用域),無論有沒有找到都會停止查找
fannie 總結
希望轉載我的博客一定要表明出處(發現多篇博客被人盜了,包括腳本之家)
此篇是你不知道的JavaScript上卷第一章。老規則,一章一篇博客(好記性不如爛筆頭 還有就是寫下來的時候 更加深一遍印象)
JavaScript進階
我們下一章見