」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 執行上下文和呼叫堆疊

執行上下文和呼叫堆疊

發佈於2024-11-08
瀏覽:133

Execution Context & Call Stack

为顶级代码创建全局执行上下文,即不在任何 fn 内的代码。因此,首先执行 fn 之外的代码。
fn-decln/exprsn 的 fn 主体内的代码仅在调用时执行。

执行上下文(EC)

JS执行的环境。
存储一些要执行的代码的所有必要信息,例如局部变量、传递给 fn 的 args。
JS 代码总是在 EC 内部运行。
无论 JS 项目有多大,都是一个全球 EC。
默认上下文,为不在任何 fn 内的代码创建。
然后代码在全局EC内部执行
顶层代码执行完毕后,执行fns &等待C/bs
对于每个 fn 调用,都会创建一个新的 EC 来执行该 fn。方法也是如此,因为它们也是附加到对象的 fns。
所有这些 EC 共同构成了调用堆栈。
当所有 fns 执行完毕后,引擎等待 CB 到达并执行它们。前任。点击事件回调,由事件循环提供。

EC里面有什么

  1. 变量环境由
  2. 组成
  3. let、const、var 声明
  4. 功能
  5. arguments 对象:将传递给 fn 的所有参数存储在其 EC 中。
    每个 fn 都有自己的 EC 作为其名称。声明的变量最终出现在变量环境中

  6. 范围链:
    Fns 可以使用作用域链访问 fns 之外的变量。
    包含对位于当前 fn 之外的变量的引用并跟踪作用域链,它存储在每个 EC 中。

  7. 每个EC也获得'this'关键字。

以上三个都是在执行之前的“创建阶段”生成的。这些是在顶层运行代码所必需的。

对于箭头 fns EC:

我们不会有:arguments 对象、this 关键字。箭头 fns 使用最接近的常规 fn,即上述两个。

arguments:类数组对象,包含传递到常规 fn 的所有参数,而不是箭头 fn。

调用栈内存堆=JS引擎

调用栈

EC 相互堆叠的地方,以跟踪我们在执行中的位置。最顶层的 EC 是我们正在运行的 EC。当执行结束时,它从堆栈顶部移除,控制权被转移到底层 EC。
如果存在嵌套的 fn 调用,由于 JS 只有一个执行线程,因此会暂停外层 fn 调用,以便在调用堆栈上返回内层 fn 的执行结果。现在前一个 EC 将成为活动 EC
然后最顶层的 EC 在返回时从调用堆栈中弹出。
调用堆栈中最低的将是全局 EC,最上面的将是按顺序发生的 fn 调用。
确保执行顺序永远不会丢失。
最终程序完成,全局EC也将弹出Call Stack。

JS 代码在 EC 内部运行,EC 放置在 Call Stack 上。

Hence, we can say that each EC has:
1. Variable environment
2. Scope chain
3. 'this' keyword

范围界定

JS引擎如何组织和访问我们的程序变量。
变量存在于哪里
我们可以在哪里访问某些变量,在哪里不能访问。

词汇范围:

JS 具有 Leical 作用域,这意味着作用域是通过代码中 fns 和块的放置来控制的。
前任。嵌套 fn 可以访问其父 fn 的变量。

范围:

声明某个变量的空间或环境(如果是 fns 则为变量环境)。它的变量 env 存储在 fns EC 中。
对于 fns,Var env 和作用域都是相同的。

Three scopes in JS are:
1. Global scope
2. Fn scope
3. Block scope [ES6]

作用域是声明变量的地方。因此,对于 Fns 也是如此,因为 fns 只是存储在变量中的值。

变量的范围

可以访问某个变量的代码区域。

作用域与变量的作用域有细微的差别。

## Global Scope:
For top level code
For variables declared outside of any fn or block which are accessible from everywhere
Variables in this scope are at the top of scope chain. Hence, can be used by every nested scope.
## Fn Scope:
Each fn has creates its own scope
Variables are accessible ONLY inside fn, NOT outside. Else Reference Error
Also called local scope
Fn decln, exprsn, arrow all three create their own scopes.
Only way to create scope using ES5 which had only fn & global scope.
## Block Scope:
Introduced in ES6, not only fn but {} also create a scope known as block scope which work only for ES6 variables i.e let-const types. DOesn't work for variables declared with 'var' as its fn scoped.
Variables accessible only inside block i.e {} 
This only applies to variables declared with let-const only.
Fns are also block scoped in ES6 (only in strict mode, should be used)
variables declared using 'var' will be accessible outside the block
Scoped to the current fn or the global scope.
var variables only care about fn, they ignore blocks. They end up in nearest fn scope.

每个嵌套作用域都可以访问其外部作用域和全局作用域中的变量。同样也适用于 fn 参数。

如果 fn 在其作用域中找不到该变量,它将查找作用域链以找出其外部作用域中的变量。这个过程称为作用域链中的变量查找。反之则不行,即我们无法从 fn 或外部作用域之外访问嵌套的 fn 变量或作用域。
同级作用域无法访问彼此的变量
只有最内层作用域可以访问其外层作用域,反之则不然。

每个 fn 的一个 EC 按照调用 fn 的确切顺序放置在调用堆栈上,其变量位于 EC 内。 Global EC 位于调用堆栈的底部

作用域链:
这完全取决于 fns 在代码中的编写顺序。
与调用 fns 的顺序无关。
作用域链从EC获取变量环境。
fn 调用的顺序与作用域链根本无关。

const a = 'Alice';
first();

function first(){
  const b = "Hello";
  second();

  function second(){
    const c = "Hi";
    third();
  }
}

function third(){
  const d = "Hey";
  console.log(d   c   b   a); // Reference Error
}

## Call Stack order:
third() EC - top
second() EC
first() EC
global EC - bottom


Scope Chain:
second() --nested inside--> first() --nested inside--> global scope.
third() is independently defined inside gloabal scope.

Reference Error occurred because both 'c' as well as 'b' cannot be accessed using the scope chain.

概括:
E-C、Var Env、Cl-Sk、Scope、Scope-chain 都是不同但相关的概念。
范围界定提出了以下问题:变量存在于何处,我们可以在哪里访问变量,在哪里不能访问变量。
JS 中的词法作用域:我们可以访问变量的规则完全基于代码中 fns 和块的写入位置。
每个作用域都可以访问其所有外部作用域的所有变量。这是范围链,是一条单向街道。外部作用域永远无法访问内部作用域的变量。
某个作用域的作用域链等于将所有父作用域的所有 Var Env 加在一起。
作用域链与 fns 的调用顺序无关。它根本不影响作用域链。
当在当前作用域中找不到变量时,引擎会查找作用域链,直到找到所需的变量。这称为变量查找。

版本聲明 本文轉載於:https://dev.to/mahf001/execution-context-call-stack-29kp?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 動態資料管理:了解 Vue.js 中的資料屬性
    動態資料管理:了解 Vue.js 中的資料屬性
    Vue.js 是用於開發現代 Web 應用程式的最受歡迎的 JavaScript 框架之一。它提供了一種創建互動式動態應用程式的有效方法。在本文中,我們將深入研究 Vue.js 中的 data 屬性,並探討它的工作原理、為什麼要使用它以及圍繞它的最佳實踐。 什麼是資料屬性? 在Vu...
    程式設計 發佈於2024-11-08
  • 如何有效地檢查 Python 字串中是否存在列表元素?
    如何有效地檢查 Python 字串中是否存在列表元素?
    檢查Python 中字串中清單元素的存在Python 程式設計中的一個常見任務是驗證字串是否包含給定的元素列表。傳統方法採用 for 循環,如下面的程式碼所示:extensionsToCheck = ['.pdf', '.doc', '.xls'] for extension in extensio...
    程式設計 發佈於2024-11-08
  • \'window.JSON\' 如何在現代瀏覽器中提供本機 JSON 支援?
    \'window.JSON\' 如何在現代瀏覽器中提供本機 JSON 支援?
    瀏覽器原生JSON 支援:window.JSON 物件瀏覽器原生JSON 支援:window.JSON 物件window.JSON 物件為現代Web 瀏覽器提供原生JSON 解析與序列化功能,實現結構化資料的高效能、安全處理。本文探討了該物件的詳細信息,包括其支援的方法和瀏覽器相容性。 window...
    程式設計 發佈於2024-11-08
  • Java 中的介面繼承自物件類別嗎?
    Java 中的介面繼承自物件類別嗎?
    介面與物件類別:繼承與方法呼叫在Java 中,介面提供了一種定義類別可以實現的契約的方法。在考慮介面和Object類別的關係時,就提出了繼承的問題。 介面是否繼承自Object類別? 答案是否。介面不繼承自Object 類別。與類別不同,所有介面都不會隱式繼承任何公共根介面。 介面實例上的方法呼叫儘...
    程式設計 發佈於2024-11-08
  • Python:有趣的程式碼模式
    Python:有趣的程式碼模式
    我主要使用 Python 工作,幾乎每天都會檢查程式碼。在我們的程式碼庫中,格式化和 linting 由 CI 作業使用 black 和 mypy 處理。因此,我們只關注變化。 在團隊中工作時,您已經知道某個團隊成員會寫什麼樣的程式碼。當新人加入團隊時,程式碼審查會變得有趣。我說有趣,是因為每個人...
    程式設計 發佈於2024-11-08
  • 在 Laravel 中使用 Redis 進行快取:逐步指南
    在 Laravel 中使用 Redis 進行快取:逐步指南
    Introduction Laravel is, without fear of contradiction, the most popular PHP framework, and among the most popular within web development. Re...
    程式設計 發佈於2024-11-08
  • 釋放即時 UI 的力量:使用 React.js、gRPC、Envoy 和 Golang 串流資料的初學者指南
    釋放即時 UI 的力量:使用 React.js、gRPC、Envoy 和 Golang 串流資料的初學者指南
    作者:Naveen M 背景 作为 Kubernetes 平台团队的一部分,我们面临着提供用户工作负载实时可见性的持续挑战。从监控资源使用情况到跟踪 Kubernetes 集群活动和应用程序状态,每个特定类别都有许多开源解决方案。然而,这些工具往往分散在不同的平台上,导致用户体验支离...
    程式設計 發佈於2024-11-08
  • 建立您自己的作業系統(真的!):初學者 C 編程
    建立您自己的作業系統(真的!):初學者 C 編程
    建立自己的作業系統:安裝 C 編譯器和工具,如 MinGW-w64。使用彙編語言編寫引導程序,載入核心。用 C 語言建立內核,包括命令解釋器。使用 Makefile 將引導程式和核心組合為“os.img”檔案。在 VirtualBox 等虛擬機器或硬體上執行「os.img」檔案。 創建自己的作業系統...
    程式設計 發佈於2024-11-08
  • 如何在 C++ 中複製 Python 的startswith() 和子字串到整數功能?
    如何在 C++ 中複製 Python 的startswith() 和子字串到整數功能?
    在C 中檢查前綴字串是否存在並將子字串轉換為整數使用者尋求有關實作Python 字串前綴檢查和子字串轉換的指導在C 。具體來說,他們的目標是實現Python的startswith()方法以及子字串轉換為整數的功能。 檢查前綴字串是否存在檢查C字串是否開始使用特定前綴,利用搜尋位置為零的 rfind(...
    程式設計 發佈於2024-11-08
  • 如何防止 Matplotlib 視覺化中出現重疊註解?
    如何防止 Matplotlib 視覺化中出現重疊註解?
    Matplotlib 中的重疊註釋Matplotlib 視覺化經常遇到重疊註釋的問題,導致圖表混亂且難以解釋。本文提供了一個全面的解決方案來應對這項挑戰。 Herausforderung當多個註釋共享同一螢幕空間時,就會出現重疊註釋,從而造成視覺混亂。在提供的程式碼中,資料點的註解文字往往會重疊,尤...
    程式設計 發佈於2024-11-08
  • 如何提高資料庫效能?主要發動機基本資源指南
    如何提高資料庫效能?主要發動機基本資源指南
    資料庫效能調優基本指南資源資料庫效能調優對於最佳化任何資料庫應用程式的效率和回應能力至關重要。為了幫助您提高該領域的知識,這裡提供了涵蓋主要資料庫引擎的可信任資源的綜合清單:General SQL 書籍:SQL效能調優SQL調優SQL 藝術重構SQL 應用程式 資料庫調優:原理、實驗與故障排除技術線...
    程式設計 發佈於2024-11-08
  • Franken UI:強大的 HTML-First UI 元件庫
    Franken UI:強大的 HTML-First UI 元件庫
    Franken UI 是一個開源庫,提供了一整套 UI 元件,設計為 HTML 優先和 Tailwind CSS 友好。無論您是建立簡單的網頁還是複雜的應用程序,Franken UI 都提供了一個多功能工具包,可以與您現有的專案無縫整合。從卡片和表單到導航和實用程序,Franken UI 確保整個應...
    程式設計 發佈於2024-11-08
  • 如何在 Python 和 JavaScript 之間序列化和反序列化 JSON 中的日期時間對象
    如何在 Python 和 JavaScript 之間序列化和反序列化 JSON 中的日期時間對象
    在Python 和JavaScript 之間處理JSON 中的日期時間物件在Python 和JavaScript 之間交換資料時,經常會遇到到日期時間對象。為了確保這些物件的無縫序列化和反序列化,可以採用各種方法。 一個建議的方法是利用 Python 中 json.dumps 的「預設」參數來處理日...
    程式設計 發佈於2024-11-08
  • 如何在 JavaScript 中建立元素重複多次的陣列?
    如何在 JavaScript 中建立元素重複多次的陣列?
    建立元素重複多次的陣列在 JavaScript 中,建立元素重複多次的陣列可以透過多種方法實作。 一個簡單的方法是利用 for 迴圈並將元素增量附加到陣列中:var repeatelem = function(elem, n) { var arr = []; for (var i = 0; ...
    程式設計 發佈於2024-11-08

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3