iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0
Modern Web

從技術文章深入學習 JavaScript系列 第 10

Day 10 [其他02] [譯] 理解JavaScript中的執行上下文和執行棧

  • 分享至 

  • xImage
  •  

文章選自

原文地址:Understanding Execution Context and Execution Stack in Javascript

原文作者:Sukhjinder Arora

译文出自:掘金翻译计划

本文永久链接:github.com/xitu/gold-m…

译者:CoolRice

校对者:, CoderMing

此文參考自:子非

連結:https://juejin.im/post/6844903682283143181

來源:掘金

分享自 Bit 的博客 ❤️

使用 Bit 应用所提供的组件作为构建模块,你就是架构师。随时随地和你的团队分享、发现和开发组件,快来尝试鲜!

以下開始

甚麼是執行上下文

執行JavaScript的環境

每當執行JavaScript代碼都是在執行上下文裡面執行

執行上下文種類

  1. 全局執行上下文(一個程序只會有一個)

    最基礎的上下文,只要不是在函數裡面的代碼都是存在於全局執行上下文

    作用:

    • 創建window對象
    • 設置this的直指向window
  2. 函數執行上下文 (每當函數被調用就會產生一個執行上下文)

    後續會解釋,先有個印象就好

  3. eval 執行上下文

    eval 函數內部執行的代碼也會有自己的上下文(但因為不常用,所以先跳過吧~~~)

執行棧

首先先給大家科普棧結構是甚麼

棧是甚麼

一種數據結構,按照後進先出模式(LIFO)儲存資料

比方說下面這張圖,要變成左圖這樣要先依序裝進A、B、C,今天想要更改數據(比方說希望變成右圖)

經過步驟:

拿出C => 拿出B => 拿出A => 放進C => 放進B => 放進A

有發現嗎,後裝進去的會先被取出來(構成左圖的順序是放A放B放C,但先拿出來的一定是C)

https://ithelp.ithome.com.tw/upload/images/20200920/20124350QMsLPaGUrM.png

甚麼是執行棧

即是其他語言的調用棧,用來儲存代碼執行時候的所有執行上下文

直接來例子

例子:

function foo() {
  console.log('bar');
  bar()
}

function bar() {
  console.log('bar');
}

foo()
console.log('結束');

運行邏輯:

  1. 一開始執行JS代碼,JS引擎會立即創建全局上下文並將它壓進執行棧裡面(就是放進去)
  2. 然後執行了foo函數(非聲明!),創建 foo 上下文壓進棧裡面
  3. 接著foo函數內部運行了bar函數,創建bar上下文壓進棧裡
  4. 當bar函數執行完成就出棧
  5. foo函數執行完成出棧
  6. 所有代碼完成全局出棧

https://ithelp.ithome.com.tw/upload/images/20200920/201243503E1NXHVXGs.png

如何創建上下文

創建分成兩個步驟

  1. 創建階段
  2. 執行階段

創建階段

總共發生三件事

  1. this指向的決定
  2. 創建詞法環境
  3. 創建變量環境

this的綁定

可參考其他文章,會有更詳細的說明

詞法環境

  • 懶人包: 

    持有 標識符—變量映射 的結構

標識符: 比方說變量或是函數的名子

變量: 數據引用

  • 內部有兩種組件:
  1. 環境紀錄器:

    儲存變量和函數聲明的位子

  2. 外部環境的引用:

    可以訪問父層的詞法環境 (作用域)

  • 兩種類型:

全局環境(全局執行上下文裡面):

​ 外部環境引用指向null,在環境記錄器( 對象環境記錄器 )內的原型函數(window對象)還有任何用戶定義的全局變量

函數環境:

​ 函數內部用戶定義的變量存儲在環境記錄器( 聲明式環境記錄器 )中。並且引用的外部環境可能是全局環境,或者任何包含此內部函數的外部函數。

  • 詞法環境的內部有兩個組件:

  • 環境紀錄器

    存儲變量和函數聲明的實際位置。

變量環境

同樣是一個詞法環境(有著上面定義的詞法環境的所有屬性),其環境記錄器持有變量聲明語句在執行上下文中創建的綁定關係。

在ES6中,詞法環境組件和變量環境的一個不同就是前者被用來存儲函數聲明和變量(letconst)綁定,而後者只用來存儲var變量綁定。

執行階段

分配好變量,就可以執行了

分享自 Bit 的博客

Bit 使得在项目和应用中分享小型组件和模块变得非常简单,使您和您的团队可以更快地构建代码。随时随地和你的团队分享、发现和开发组件,快来尝鲜!

了解更多

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


上一篇
Day 09 [其他01] 7分鐘理解JS的節流、防抖及使用場景
下一篇
Day 11 [EventLoop 01] 一次弄懂Event Loop(徹底解決此類面試問題)
系列文
從技術文章深入學習 JavaScript29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言