1. 程式人生 > 實用技巧 >作用域的理解-1

作用域的理解-1

作用域 - note1(《你不知道的JavaScript》筆記,這個書寫的很有趣,可以看看)

程式var a = 2 處理時發生了啥

瞭解將要參與到對程式 var a = 2; 進行處理的過程中的演員們。

  • 引擎
    • 從頭到尾負責整個 JavaScript 程式的編譯及執行過程。
  • 編譯器
    • 引擎的好朋友之一,負責語法分析及程式碼生成等髒活累活。
  • 作用域
    • 引擎的另一位好朋友,負責收集並維護由所有宣告的識別符號(變數)組成的一系列查詢,並實施一套非常嚴格的規則,確定當前執行的程式碼對這些識別符號的訪問許可權

在處理程式var a = 2這些演員具體幹了啥

  1. 遇到 var a,編譯器會詢問作用域是否已經有一個該名稱的變數存在於同一個作用域的 集合中。如果是,編譯器會忽略該宣告,繼續進行編譯;否則它會要求作用域在當前作 用域的集合中宣告一個新的變數,並命名為 a。
  2. 接下來編譯器會為引擎生成執行時所需的程式碼,這些程式碼被用來處理 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(..)。