国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

一篇文章弄懂javascript中的執行棧與執行上下文

2024-05-06 16:54:08
字體:
來源:轉載
供稿:網友

前言

作為一個前端開發人員,弄清楚JavaScript的執行上下文有助于我們理解js中一些晦澀的概念,比如閉包,作用域,變量提升等等。

執行棧

執行棧用于存儲代碼執行期間創建的所有執行上下文。具有FILO接口,也被稱為調用棧。
當JavaScript代碼被運行的時候,會創建一個全局上下文,并push到當前執行棧。之后當發生函數調用的時候,引擎會為函數創建一個函數執行上下文并push到棧頂。引擎會先執行調用棧頂部的函數,當函數執行完成后,當前函數的執行上下文會被移除當前執行棧。并移動到下一個上下文。

let a = 'Hello'function first() {  console.log('Inside first function')  second()  console.log('Again inside first function')}function second() {  console.log('Inside second function')}first()console.log('Inside Global execution context')

javascript,執行,棧,上下文

執行上下文

我們可以理解為執行上下文是js代碼被解析和執行時所在環境的抽象概念。
JavaScript的執行上下文分為三種類型:

  • 全局執行上下文:最基本的上下文,只有一個。創建了一個全局對象(eg:瀏覽器中的window),將this指向全局對象。
  • 函數執行上下文:每次調用函數都會創建一個函數上下文。函數上下文可以存在無數個。
  • Eval函數執行上下文:運行在eval函數中的代碼會有一個自己的執行上下文(本文不討論)。

執行上下文的創建

創建執行上下文又可以分為兩個階段: 1. 創建階段 2. 執行階段

創建階段

在創建階段,JavaScript引擎會創建LexicalEnvironment(詞法環境)組件,VariableEnvironment(變量環境)組件以及this綁定(在全局上下文中,this指向全局對象。在函數執行上下文中,this取決與函數在哪里被調用。)

Lexical  Environment(詞法環境)

ES2015規范對詞法環境的描述

我們可以理解為詞法環境是一種包含標識符(變量/函數的名稱)和變量(實際對象:函數/原始值/數組對象等)映射的數據結構。

每個詞法環境由兩部分組成:Environment Record環境記錄(存儲變量和函數聲明的實際位置)和對外部環境的引用(可以訪問其外部詞法環境)

環境記錄分為兩種:

  • Declarative environment record(聲明性環境記錄): 存儲變量和函數聲明。
  • Object environment record(對象環境記錄):全局詞法環境。除了變量和函數聲明外,對象環境記錄還存儲全局綁定對象。

tips:對于函數執行上下文來說,環境記錄還包含了一個arguments對象,包含了傳遞給函數的索引和參數之間的映射以及函數參數的數量。

例如:

function foo(a, b) {  var c = a + b}// argument objectArguments: {0: 2, 1: 3, length: 2}

VariableEnvironment(變量環境)

變量環境也是一個詞匯環境,因此它具有上面定義的詞法環境的所有屬性和組件。在ES6中,LexicalEnvironment組件和VariableEnvironment組件之間的一個區別是前者用于存儲函數聲明和變量let和const綁定,而后者僅用于存儲變量var綁定。

執行階段

在執行階段,會完成對所有變量的分配,代碼也會被最終執行。執行上下文的代碼會被分成兩個階段:

  1. 進入執行上下文
  2. 代碼執行
let a = 20const b = 30var cfunction multiply(e, f) {  var g = 20  return e * f * g}c = multiply(20, 30)

當上面的代碼被執行的時候,JavaScript引擎會創建一個全局上下文來執行全局代碼。

此時的全局上下文:

GlobalExectionContext = {  // 全局上下文  LexicalEnvironment: {  // 詞法環境    EnvironmentRecord: {  // 環境記錄      type: 'Object', // 類型      // 標識符      a: <uninitialized>,      b: <uninitialized>,      multiply: <func>    },    outer: <null>, // 對外部環境引用  },  VariableEnvironment: { // 變量環境    EnvironmentRecord: {  // 環境記錄      type: 'Object',      c: undefined    },    outer: <null>, // 對外部環境引用  },  ThisBinding: <Global Object>  // this綁定}

在執行階段,變量會被賦值,此時的全局上下文變成:

GlobalExectionContext = {  LexicalEnvironment: {    EnvironmentRecord: {      type: 'Object',      a: 20,      b: 30,      multiply: <func>    },    outer: <null>  },  VariableEnvironment: {    EnvironmentRecord: {      type: 'Object',      c: undefined    }    outer: <null>  },  ThisBinding: <Global Object>}

當JavaScript引擎遇到函數multiply(20, 30)的時候,會創建一個新的函數上下文:

FunctionExectionContext = {  LexicalEnvironment: {    EnvironmentRecord: {      type: 'Declarative',      arguments: {        0: 20,        1: 30,        length: 2      }    },    outer: <GlobalLexicalEnvironment>  },  VariableEnvironment: {    EnvironmentRecord: {     Type: "Declarative",     g: undefined    },    outer: <GlobalLexicalEnvironment>,  },  thisBinding: <Global Object or undefined>}

之后執行上下文會進入執行階段, 此時的函數上下文:

FunctionExectionContext = {  LexicalEnvironment: {    EnvironmentRecord: {      type: 'Declarative',      arguments: {        0: 20,        1: 30,        length: 2      }    },    outer: <GlobalLexicalEnvironment>  },  VariableEnvironment: {    EnvironmentRecord: {     Type: "Declarative",     g: 20    },    outer: <GlobalLexicalEnvironment>,  },  thisBinding: <Global Object or undefined>}

當函數執行完畢后。會返回一個值并賦值給變量c,全局上下文被更新。更新完成后,代碼執行完畢,程序結束。

參考文章

Understanding Execution Context and Execution Stack in Javascript

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 龙江县| 丰都县| 崇左市| 济宁市| 竹溪县| 望江县| 镇平县| 嵩明县| 天峻县| 巴马| 廊坊市| 富阳市| 惠安县| 延吉市| 濮阳市| 临湘市| 克什克腾旗| 广丰县| 濮阳市| 财经| 江口县| 嫩江县| 乌兰县| 瓦房店市| 剑阁县| 张家口市| 宁乡县| 洛扎县| 景宁| 盐山县| 句容市| 安远县| 莆田市| 普陀区| 泾源县| 蒲江县| 曲沃县| 阳山县| 肇东市| 靖宇县| 繁昌县|