javascript入門到進階-js系列六:執行上下文

2021-01-20 騰訊網

javascript代碼在執行時,會進入一個執行上下文中,執行上下文可以理解為當前代碼的運行環境。

javascript中運行環境主要包括以下三種情況

> 1 全局環境:代碼運行起來首先會進入全局環境

> 2 函數環境:當函數被調用執行時,會進入當前函數中執行代碼

> 3 eval函數環境:不建議使用,這裡不做介紹。

所以在一個javascript程序中,必定會出現多種不同的執行上下文。javascript是一個單線程語言,這意味著在瀏覽器中同時只能做一件事情。當javascript解釋器初始執行代碼,它首先默認進入全局上下文。每次調用一個函數將會創建一個新的執行上下文。每次新創建的一個執行上下文會被添加到作用域鏈的頂部,有時也稱為執行或調用棧。瀏覽器總是運行位於作用域鏈頂部的當前執行上下文。一旦完成,當前執行上下文將從棧頂被移除並且將控制權歸還給之前的執行上下文。

不同執行上下文之間的變量命名衝突通過攀爬作用域鏈解決,從局部直到全局。這意味著具有相同名稱的局部變量在作用域鏈中有更高的優先級。簡單的說,每次你試圖訪問函數執行上下文中的變量時,查找進程總是從自己的變量對象開始。如果在自己的變量對象中沒發現要查找的變量,繼續搜索作用域鏈。它將攀爬作用域鏈檢查每一個執行上下文的變量對象,尋找和變量名稱匹配的值。

2>執行上下文的建立過程

我們現在已經知道,每當調用一個函數時,一個新的執行上下文就會被創建出來。然而,在javascript引擎內部,這個上下文的創建過程具體分為兩個階段:

>建立階段(發生在當調用一個函數時,但是在執行函數體內的具體代碼以前)

- - - 建立變量,函數,arguments對象,參數

- - - 建立作用域鏈

- - - 確定this的值

代碼執行階段:

- - - 變量賦值,函數引用,執行其它代碼

3>建立階段以及代碼執行階段的詳細分析

確 切地說,執行上下文對象(上述的executionContextObj)是在函數被調用時,但是在函數體被真正執行以前所創建的。函數被調用時,就是我 上述所描述的兩個階段中的第一個階段 - 建立階段。這個時刻,引擎會檢查函數中的參數,聲明的變量以及內部函數,然後基於這些信息建立執行上下文對象 (executionContextObj)。在這個階段,variableObject對象,作用域鏈,以及this所指向的對象都會被確定。

上述第一個階段的具體過程如下:

找到當前上下文中的調用函數的代碼

在執行被調用的函數體中的代碼以前,開始創建執行上下文

進入第一個階段-建立階段:

建立variableObject對象:

建立arguments對象,檢查當前上下文中的參數,建立該對象下的屬性以及屬性值

檢查當前上下文中的函數聲明:

每找到一個函數聲明,就在variableObject下面用函數名建立一個屬性,屬性值就是指向該函數在內存中的地址的一個引用

如果上述函數名已經存在於variableObject下,那麼對應的屬性值會被新的引用所覆蓋。

檢查當前上下文中的變量聲明:

每找到一個變量的聲明,就在variableObject下,用變量名建立一個屬性,屬性值為undefined。

如果該變量名已經存在於variableObject屬性中,直接跳過(防止指向函數的屬性的值被變量屬性覆蓋為undefined),原屬性值不會被修改。

初始化作用域鏈

確定上下文中this的指向對象

代碼執行階段:

執行函數體中的代碼,一行一行地運行代碼,給variableObject中的變量屬性賦值。

「實例1」

var color = "blue";

function changeColor(){

var anotherColor = "red";

function swapColor() {

var tempColor = anotherColor;

anotherColor = color;

color = tempColor;

}

swapColor();

}

changeColor();

我們用ECStack來表示處理執行上下文的堆棧第一步全局上下文入棧,並一直存在於棧底,如圖所示:

第二步,全局上下文入棧之後,從可執行代碼開始執行,直達遇到changeColor(),這句代碼激活了函數changeColor,從而創建changeColor自己的執行上下文,因此此時是changeColor ECStack的上下文入棧。

第三步,changeColor EC 的上下文入棧之後,開始執行其中的可執行代碼,並在遇到swapColor()這句代碼之後激活swapColor()執行上下文,因此第三步就是swapColor EC的上下文入棧

第四步,在swapColor的可執行代碼中,沒有其他能生成執行上下文的情況,因此這段代碼順利執行完畢,swapColor的執行上下文入棧中彈出,如圖所示

第五步,swapColor的執行上下文彈出之後,繼續執行changeColor的可執行代碼,遇到其他執行上下文,順利執行完畢後彈出,這樣ECStack就剩下全局執行上下文了,如圖所示

最後,,全局執行上下文在瀏覽器關閉後出棧。需要注意的是,函數執行上下文遇到 return 能直接終止可執行代碼的執行,因此會直接將當前上下文彈出棧。

「實例2」

function f1() {

var n = 999;

function f2() {

console.log(n);

}

return f2;

}

var result = f1();

result();

這是一個閉包的例子,整個例子有一定的迷惑性但是我們只需要根據「函數執行才會創建執行上下文」這一個原則來理解,那麼這段代碼執行時的函數調用棧順序就會比較清晰了。第一步,仍然是全局上下文先入棧,如圖所示

第二步,就是全局代碼在執行過程中,遇到了f1()函數,執行var result = f1();,因此f1會創建對應的執行上下文併入棧,

第三步,在f1的可執行代碼中,雖然聲明了一個函數f2,但是並沒有執行任何函數,因此也就不會產生別的執行上下文,代碼執行結束後,f1自然會出棧,如圖所示

第四步,f1出棧之後,繼續執行全局上下文的代碼,這個時候遇到了result(),result()函數會創建一個新的執行上下文,因此這個時候result的上下文入棧,如圖

第五步,這個result()其實就是在f1中聲明的函數f2,因此這個時候就會執行f2的代碼,由於f2中沒有產生新的執行上下文,因此執行完畢後直接出棧

相關焦點

  • 學好前端的基礎與難點:js執行上下文及其運行原理
    同樣的,對程序語言進行「解讀」的時候,也必須在特定的語境中,這個語境就是javascript中的執行上下文。執行上下文是什麼?以上是javascript上下文的通俗理解,標準的說法是,執行上下文(Execution Context)是javascript代碼執行的環境,js代碼一定是在執行上下文中執行的。
  • JavaScript入門
    JavaScript技術除了JavaScript語法外,還包括HTML DOM技術,以及jQuery、Angular JS、React、Node.js、Vue.js等衍生技術,目前在前端開發中,建議掌握JavaScript語法、HTML DOM和Vue.js技術。本文主要講解一些JavaScript的入門知識。
  • 這一次,徹底弄懂 JavaScript 執行機制
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫本文的目的就是要保證你徹底弄懂JavaScript的執行機制,如果讀完本文還不懂,可以揍我。
  • 了解 JavaScript 執行上下文
    為了讓大家迅速的對執行上下文建立一個概念性的認知,所以本篇文章並不會對執行上下文做過深的討論,但後面的文章,會結合執行上下文詳細解釋引言中提到的問題。到此為止,關於執行上下文,您暫時只需要了解這麼多。執行上下文棧在一個完整的 JavaScript 程序中,有任意數量的函數上下文需要運行,但 JavaScript 如何管理它們呢?在瀏覽器中,JavaScript 解釋器是單線程的。
  • 前端技術:JavaScript進階篇
    如果是傳統寫法,通過監聽事件來執行回調函數,一旦錯過了事件,再添加回調函數是不會執行的。4.作用域和閉包1.執行上下文執行上下文主要有兩種情況:全局代碼:一段script標籤裡,有一個全局的執行上下文。所做的事情是:變量定義、函數聲明【在執行全局代碼前將window確定為全局執行上下文.】函數代碼:每個函數裡有一個上下文。
  • JavaScript入門,為什麼要學習JavaScript?
    </body></html>這樣,/static/js/abc.js就會被瀏覽器執行。把JavaScript代碼放入一個單獨的.js文件中更利於維護代碼,並且多個頁面可以各自引用同一份.js文件。可以在同一個頁面中引入多個.js文件,還可以在頁面中多次編寫<script> js代碼...
  • JavaScript入門教程
    起源javascript前身叫做livescript,sun公司推出java,netspace公司引進java的概念,重新設計livescript,並更名javascript。發明者,布蘭登.艾克,表單驗證原先要經過伺服器,伺服器壓力大,等待時間長,js僅在客戶端就可完成。是什麼是一種腳本語言,是一種輕量級的程式語言。
  • JS教程之JavaScript進階之路要看哪些書?
    前端入門的門檻相對較低,學習曲線是越來越陡峭,由淺入深,可以分為四個階段。你可以從網上找到更多更詳細的資料來繼續學習,比如百度搜索「php中文網js視頻教程」。以下是介紹的一些js進階需要看的書籍。學習Javascript,用《JavaScript DOM編程藝術》來入門最好不過了,老老實實看兩遍,看完了你就會對JS有一個大概的了解,整本書都圍繞著一個網頁效果例子展開,跟著老老實實敲一篇,敲完之後,發現自己也能做出來網上的效果了。
  • [分享]Rhino使JavaScript應用程式更靈動
    將軟體包解壓,可以得到Rhino原始碼、文檔、測試代碼、樣例以及一些小工具,利用這些我們便可以通過多種方式執行JavaScript腳本。使用交互模式調用JS解釋器1.進入交互模式進入交互模式有兩種方式:使用 js.jar文件實現和使用org.mozilla.javascript.tools.shell實現。
  • 前端基礎進階(二):執行上下文詳細圖解
    棧底永遠都是全局上下文,而棧頂就是當前正在執行的上下文。當代碼在執行過程中,遇到以上三種情況,都會生成一個執行上下文,放入棧中,而處於棧頂的上下文執行完畢之後,就會自動出棧。為了更加清晰的理解這個過程,根據下面的例子,結合圖示給大家展示。執行上下文可以理解為函數執行的環境,每一個函數執行時,都會給對應的函數創建這樣一個執行環境。
  • 一篇文章帶你快速入門JavaScript(實操代碼)
    文件,在js文件中編寫js代碼。(外部文件中編寫js代碼就直接寫代碼就可以了,不用再添加script標籤)比如說在js目錄下面創建一個 test.js文件 裡面的代碼為alert(「出錯啦!」)DOCTYPE html><html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script src="js/test.js" type="text/javascript&
  • 「 原創 」理解 JavaScript 中抽象的執行上下文
    乍一看,執行上下文這個概念確實抽象,特別是初學 JavaScript 時,若是未深入去了解的情況下,被問及什麼是執行上下文,或者說說你對執行上下文的理解的時候,就更顯得茫然不知所措了。在瀏覽器中,只有當瀏覽器關閉或者程序退出的時候,該執行上下文才會被銷毀,也就是說在 JavaScript 程序啟動後,首先創建了一個全局的執行上下文,且在銷毀前一直都處於執行棧的最底層。
  • GitHub 上周 JavaScript 趨勢榜項目(第23周)
    9. airbnb/javascript項目地址:https://github.com/airbnb/javascript⭐:96360 | forks:18750 | 696 stars this weekJavaScript
  • 七天學會javascript第一天javascript介紹
    前幾周寫了幾篇關於入門php的文章,反響還不錯,之前簡單的提到了JavaScript,這周小編重點介紹JavaScript讓大家可以在一周時間內掌握這門前端語言的基本用法。javascript介紹javascript數據類型javascript運算符javascript對象javascript Date對象javascript String對象JavaScript常用於實現一些前端效果。前些年流行的flash已經慢慢的被淘汰,js盛行起來。javascript :客戶端編程。javascript是由客戶端去解釋運行的。
  • 前端面試之Js預編譯
    js預編譯是前端平時面試筆試題的必考題,預編譯能夠很大程度的考察面試者的js基礎,所以也是現如今各大公司的熱門考點。其實預編譯就是js代碼執行過程中的一個階段,那麼js代碼執行的過程是怎麼樣的呢?js代碼執行步驟主要有三個階段:首先是檢查代碼通篇的語法錯誤其次就是js的預編譯過程了最後就是代碼的實際執行過程(解釋一行,執行一行)下面簡單的看一段代碼(預熱一下):(a) test() function test() { console.log
  • 「GitHub」 JavaScript 趨勢榜項目(第33周)
    11. jonasschmedtmann/complete-javascript-course項目地址:https://github.com/jonasschmedtmann/complete-javascript-course⭐:4,380
  • 五分鐘了解asm.js和WebAssembly
    asm.js是一種提升js執行效率的解決方案。asm.js能帶來非常高的效率提升。甚至能讓瀏覽器運行3d遊戲。底層的。底層到什麼程度呢?就相當於是瀏覽器js引擎中的C語言了。asm.js它的變量一律都是靜態類型,並且取消垃圾回收機制。當瀏覽器的JavaScript 引擎發現運行的是 asm.js時,就會跳過語法分析這一步,將其轉成彙編語言執行。
  • 基於TensorFlow.js的JavaScript機器學習
    Credits: aijs.rocks雖然python或r程式語言有一個相對容易的學習曲線,但是Web開發人員更喜歡在他們舒適的javascript區域內做事情。目前來看,node.js已經開始向每個領域應用javascript,在這一大趨勢下我們需要理解並使用JS進行機器學習。由於可用的軟體包數量眾多,python變得流行起來,但是JS社區也緊隨其後。
  • 初識javascript,JS的歷史_騰訊新聞
    javascript和H5的關關係 什麼是HTML5? javascript的應用範圍 1.PC端web開發(網站) 2.移動端開發(webApp、混合App)服務端開發(NodeJs) 3.遊戲開發(unity3D-TypeScript,網頁遊戲)在線演示:忍者水果
  • JavaScript企業容器:從Java到Node.js
    我們來看看一個開源項目,並討論為什麼它是使用Node.js的企業應用程式和微服務的靈活開發環境。本文為Java和JavaScript開發人員介紹了「 JavaScript Enterprise Container 」(JEC)項目。它將展示一個靈活的開發環境,用於構建Node.js上的企業應用程式和微服務。