首頁 >web前端 >js教程 >JavaScript塊級作用域的實作原理(圖文詳解)

JavaScript塊級作用域的實作原理(圖文詳解)

WBOY
WBOY轉載
2022-02-01 06:00:312945瀏覽

本篇文章帶給大家關於JavaScript中區塊級作用域的實作原理相關知識,在ES6之前,區塊級作用域是不被JavaScript所支援的,JavaScript是透過什麼支援了區塊級作用域的呢?本文將講解塊級作用域的底層實現原理,希望對大家有幫助。

JavaScript塊級作用域的實作原理(圖文詳解)

作用域與執行上下文

很多人覺得作用域與執行上下文是一個概念,這種想法是完全錯誤的!

作用域

作用域在函數宣告時就已經確定了,作用域是據名稱來找出變數的一套規則,也就是確定了目前執行程式碼對變數的存取權限。 JavaScript一共支援三種類型的作用域,它們分別是:全域作用域、函數作用域、區塊層級作用域。

執行上下文

執行上下文是js引擎從解釋到運行中間預編譯時對執行做的準備工作,創建了當前區域的執行環境,這個執行環境就是執行上下文。

執行堆疊

呼叫堆疊用來裝js程式碼中的各種執行上下文,是js引擎追蹤函數執行的一個機制。

以下面的程式碼為例:

console.log(1);
function pFn() {
    console.log(2);
    (function cFn() {
        console.log(3);
    }());
    console.log(4);
}
pFn();
console.log(5);
//输出:1 2 3 4 5

先有全域環境下的執行上下文,呼叫pFn後將函數環境pFn的執行上下文壓入堆疊中,由於pFn中執行了cFn函數,所以繼續壓入cFn函數的執行上下文,執行完畢後依序出棧。

全域上下文只有應用程式退出前才會被銷毀,例如關閉網頁或退出瀏覽器

JavaScript塊級作用域的實作原理(圖文詳解)

javascript 是如何支援區塊級作用域的

我們知道在js中由於初始設計的不規範,用var關鍵字定義變數會導致變數提升等一系列問題,但為了保持相容性,我們也不得不對var宣告變數保留支持,那麼:JavaScript是如何做到既要支援變數提升,又要支援區塊級作用域的呢?

我們以下面這段程式碼為例:

function foo() {
   var a = 1;
   let b = 2;
   {
   let b = 3;
   var c = 4;
   let d = 5;
   console.log(a);
   console.log(b);
   }
   console.log(b);
   console.log(c);
   console.log(d);
}

首先函數內部透過var宣告的變數被存放到變數環境中,透過let宣告的變數在預編譯階段被存放到詞法環境中,當然在函數體內部塊作用域中let宣告的變數並沒有被存放到詞法環境。

JavaScript塊級作用域的實作原理(圖文詳解)

繼續執行程式碼,當執行到程式碼區塊裡面時,變數環境中的a的值已經設定為1,詞法環境中b的值已經設定成了2,注意用let宣告的變數b和d此時不是underfined而是uninitialized未初始化

JavaScript塊級作用域的實作原理(圖文詳解)

#最後當函數體內區塊作用域執行結束之後,其內部變量就會從詞法環境的棧頂彈出

JavaScript塊級作用域的實作原理(圖文詳解)

總結

#我們可以知道上面問題的答案:

用let 宣告出來的變數中都會在詞法環境中存放,塊級作用域是透過詞法環境的堆疊結構來實現的,而變數提升是透過變數環境來實現的,兩者結合同時支援變數提升和區塊級作用域

以及變數的查找方式:

從詞法環境的作用域堆疊頂開始向下查找,如果找到了就回傳值,如果找不到,就繼續去變數環境中找

相關推薦:javascript學習教學

#

以上是JavaScript塊級作用域的實作原理(圖文詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除