js執行上下文和執行棧


執行上下文就是JavaScript 在被解析和運行時環境的抽象概念,JavaScript 運行任何代碼都是在執行上下文環境中運行的,執行上下文包括三個周期:創建——運行——銷毀,重點說一下創建環節。

創建環節(函數被調用,但未未被執行)會執行三件事情

  • 創建變量對象,首先初始化函數的arguments對象,提升函數聲明和變量聲明,從近到遠查找函數運行所需要的變量。
  • 創建作用域鏈,作用域就是一個獨立的地盤,讓變量不會相互干擾,當前作用域沒有定義的變量,這成為 自由變量。自由變量會向上一直尋找,要到創建這個函數的那個作用域中取值——是“創建”,而不是“調用”,如果最終沒有就為undefined。這種層層之間就構成了作用域鏈。
  • 確定this指向,this、apply、call的指向
function test(arg){
        // 1. 形參 arg 是 "hi"
        // 2. 因為函數聲明比變量聲明優先級高,所以此時 arg 是 function
        console.log(arg);
        var arg = 'hello'; // 3.var arg 變量聲明被覆蓋, arg = 'word'被執行
        function arg(){
            console.log('hello world')
        }
        var arg = 'word';
        console.log(arg);
    }
    test('hi');

可以看下上面這個例子,函數內函數聲明比變量聲明優先,所以arg被覆蓋,並且被提升,所以第一次打印不會報錯,打出了arg函數,后面變量被覆蓋成為hello。

函數執行多了就會有多個執行上下文,那么怎么管理這些執行上下文呢?

JavaScript 引擎創建了執行棧來管理執行上下文,可以把執行棧認為成一個儲存函數調用的棧結構,遵循先進后出的原則。

從上面代碼執行,我們大概可以得出以下幾點

  • JavaScript引擎是單線程執行,所有代碼都是排隊執行。
  • 一開始執行的是全局代碼,首先創建全局的執行上下文,然后將該執行上下文壓入執行棧中。
  • 每當執行一個函數,就會創建該函數的執行上下文,然后將其壓入執行棧的頂部,函數執行完成后,執行上下文從底部退出,等待垃圾回收。
  • 游覽器js總是訪問執行棧頂層的執行上下文。
  • 全局上下文只有唯一的一個,它在瀏覽器關閉時出棧

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM