web前端教程之JavaScript的作用域

千鋒武漢發表於2021-04-07

      作為一個前端工程師,你必須對JavaScript的作用域不陌生,傳統常見的有函式級作用域,還有全域性作用域,ES6 let const 的塊級作用域,其實還有一個你不知道的塊級作用域,今天小千就來給大家介紹一下。

      我們先來看看下面這個段程式碼,請思考一下結果是什麼。

1

      想必你心中已經有了結果,答案是 3  2

      你答對了嗎?答案結果是否有些意外呢?

      好了,我們來看看為什麼會出現這個答案? 首先我們需要先了解以下基本知識。

      宣告提前

      宣告提前指的是JS引擎在執行之前對程式碼進行的預解析(為了提高執行效率) 具體的來說就是使用(var)宣告變數和(function)宣告的函式正預編譯階段將其提升到了作用域的頂部

      全域性變數宣告

2

      函式作用域變數宣告

3

      函式宣告

4

      函式表示式宣告

5

      函式塊級作用域

      透過下面程式碼我們可以知道 變數的宣告是沒有塊級作用域的,if語句塊中宣告的變數foo會提升到全域性作用域並初始化值為undefined

6

      我們再看看函式的情況

7

      上面這個例子告訴我們 函式foo提升到了if語句塊的頂部,但是沒有提升到全域性作用域的頂部。但全域性作用域中存有一個名為foo的變數 在程式碼執行後同步成了函式foo

      同步?為什麼會有同步?我們來看看觀察上帝視角的神器 ———— 斷點除錯。 我這邊監聽了 foo 變數和 window.foo 大家請注意一下它的變化。 同時我們也關注一下 Scope 作用域

      我們看到Scope中只有全域性作用域 foo和window.foo的只都是undefined

8

      程式碼執行到if語句塊中 我們再Scope中又發現了一個新的塊級作用域 當前塊級作用域foo的值被賦值為一個函式(函式提升) 而全域性作用域中的foo依舊是undefined

9

      程式碼繼續往後執行 執行函式的賦值 block作用域依然存在 我把幾個變數的值使用箭頭進行了對應

10

      神奇的地方來了 在函式執行賦值後 塊級作用域消失 而全域性變數的foo同步成了剛才塊級作用域的foo

11

      迴歸原題

      我們對foo變數進行隔行輸出 看看結果

12

      結合上面斷點測試的結果大家可以發現,函式在程式碼塊中宣告會提前到塊級作用域頂部,預編譯結束後開始執行程式碼 在執行階段任然會執行函式的賦值操作,其實是函式賦值的第二次執行(第一次在預編譯階段) 第二次的賦值執行的意義是確認當前 函式/全域性 作用域能準確的檢索到函式 所以講函式同步到了 當前的函式或全域性作用域中。

      好了本次解析就到這裡,還有不明白的小夥伴可以copy程式碼去進行斷點測試,相信很快你能理解其中奧秘。 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31548651/viewspace-2766809/,如需轉載,請註明出處,否則將追究法律責任。

相關文章