真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

一篇文章弄懂javascript中的執(zhí)行棧與執(zhí)行上下文

前言

企業(yè)建站必須是能夠以充分展現(xiàn)企業(yè)形象為主要目的,是企業(yè)文化與產(chǎn)品對外擴(kuò)展宣傳的重要窗口,一個合格的網(wǎng)站不僅僅能為公司帶來巨大的互聯(lián)網(wǎng)上的收集和信息發(fā)布平臺,成都創(chuàng)新互聯(lián)公司面向各種領(lǐng)域:成都衛(wèi)生間隔斷成都網(wǎng)站設(shè)計、成都營銷網(wǎng)站建設(shè)解決方案、網(wǎng)站設(shè)計等建站排名服務(wù)。


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

執(zhí)行棧

執(zhí)行棧用于存儲代碼執(zhí)行期間創(chuàng)建的所有執(zhí)行上下文。具有FILO接口,也被稱為調(diào)用棧。
當(dāng)JavaScript代碼被運(yùn)行的時候,會創(chuàng)建一個全局上下文,并push到當(dāng)前執(zhí)行棧。之后當(dāng)發(fā)生函數(shù)調(diào)用的時候,引擎會為函數(shù)創(chuàng)建一個函數(shù)執(zhí)行上下文并push到棧頂。引擎會先執(zhí)行調(diào)用棧頂部的函數(shù),當(dāng)函數(shù)執(zhí)行完成后,當(dāng)前函數(shù)的執(zhí)行上下文會被移除當(dāng)前執(zhí)行棧。并移動到下一個上下文。

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中的執(zhí)行棧與執(zhí)行上下文

執(zhí)行上下文

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

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

執(zhí)行上下文的創(chuàng)建

創(chuàng)建執(zhí)行上下文又可以分為兩個階段: 1. 創(chuàng)建階段 2. 執(zhí)行階段

創(chuàng)建階段

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

Lexical  Environment(詞法環(huán)境)

ES2015規(guī)范對詞法環(huán)境的描述

我們可以理解為詞法環(huán)境是一種包含標(biāo)識符(變量/函數(shù)的名稱)和變量(實(shí)際對象:函數(shù)/原始值/數(shù)組對象等)映射的數(shù)據(jù)結(jié)構(gòu)。

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

環(huán)境記錄分為兩種:

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

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

例如:

function foo(a, b) {
  var c = a + b
}

// argument object
Arguments: {0: 2, 1: 3, length: 2}

VariableEnvironment(變量環(huán)境)

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

執(zhí)行階段

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

  1. 進(jìn)入執(zhí)行上下文
  2. 代碼執(zhí)行
let a = 20
const b = 30
var c

function multiply(e, f) {
  var g = 20
  return e * f * g
}

c = multiply(20, 30)

當(dāng)上面的代碼被執(zhí)行的時候,JavaScript引擎會創(chuàng)建一個全局上下文來執(zhí)行全局代碼。

此時的全局上下文:

GlobalExectionContext = {  // 全局上下文
  LexicalEnvironment: {  // 詞法環(huán)境
    EnvironmentRecord: {  // 環(huán)境記錄
      type: 'Object', // 類型
      // 標(biāo)識符
      a: ,
      b: ,
      multiply: 
    },
    outer: , // 對外部環(huán)境引用
  },
  VariableEnvironment: { // 變量環(huán)境
    EnvironmentRecord: {  // 環(huán)境記錄
      type: 'Object',
      c: undefined
    },
    outer: , // 對外部環(huán)境引用
  },
  ThisBinding:   // this綁定
}

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

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

當(dāng)JavaScript引擎遇到函數(shù)multiply(20, 30)的時候,會創(chuàng)建一個新的函數(shù)上下文:

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

之后執(zhí)行上下文會進(jìn)入執(zhí)行階段, 此時的函數(shù)上下文:

FunctionExectionContext = {
  LexicalEnvironment: {
    EnvironmentRecord: {
      type: 'Declarative',
      arguments: {
        0: 20,
        1: 30,
        length: 2
      }
    },
    outer: 
  },
  VariableEnvironment: {
    EnvironmentRecord: {
     Type: "Declarative",
     g: 20
    },
    outer: ,
  },
  thisBinding: 
}

當(dāng)函數(shù)執(zhí)行完畢后。會返回一個值并賦值給變量c,全局上下文被更新。更新完成后,代碼執(zhí)行完畢,程序結(jié)束。

參考文章

Understanding Execution Context and Execution Stack in Javascript

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對創(chuàng)新互聯(lián)的支持。


文章標(biāo)題:一篇文章弄懂javascript中的執(zhí)行棧與執(zhí)行上下文
文章URL:http://weahome.cn/article/jcjcdi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部