你不知道的JavaScript之作用域

什麼是作用域

編譯原理

  • 分詞/詞法分析

    這個過程會將由字符組成的字符串分解成(對編程語言來說)有意義的代碼塊,這些代 碼塊被稱爲詞法單元(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進階 

  我們下一章見

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章