”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 执行上下文和调用堆栈

执行上下文和调用堆栈

发布于2024-11-08
浏览:386

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]删除
最新教程 更多>
  • Python中嵌套函数与闭包的区别是什么
    Python中嵌套函数与闭包的区别是什么
    嵌套函数与python 在python中的嵌套函数不被考虑闭合,因为它们不符合以下要求:不访问局部范围scliables to incling scliables在封装范围外执行范围的局部范围。 make_printer(msg): DEF打印机(): 打印(味精) ...
    编程 发布于2025-04-27
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-04-27
  • 在Python中如何创建动态变量?
    在Python中如何创建动态变量?
    在Python 中,动态创建变量的功能可以是一种强大的工具,尤其是在使用复杂的数据结构或算法时,Dynamic Variable Creation的动态变量创建。 Python提供了几种创造性的方法来实现这一目标。利用dictionaries 一种有效的方法是利用字典。字典允许您动态创建密钥并分...
    编程 发布于2025-04-27
  • \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    \“(1)vs.(;;):编译器优化是否消除了性能差异?\”
    答案: 在大多数现代编译器中,while(1)和(1)和(;;)之间没有性能差异。编译器: perl: 1 输入 - > 2 2 NextState(Main 2 -E:1)V-> 3 9 Leaveloop VK/2-> A 3 toterloop(next-> 8 last-> 9 ...
    编程 发布于2025-04-27
  • 在JavaScript中如何并发运行异步操作并正确处理错误?
    在JavaScript中如何并发运行异步操作并正确处理错误?
    同意操作execution 在执行asynchronous操作时,相关的代码段落会遇到一个问题,当执行asynchronous操作:此实现在启动下一个操作之前依次等待每个操作的完成。要启用并发执行,需要进行修改的方法。 第一个解决方案试图通过获得每个操作的承诺来解决此问题,然后单独等待它们: co...
    编程 发布于2025-04-27
  • PHP SimpleXML解析带命名空间冒号的XML方法
    PHP SimpleXML解析带命名空间冒号的XML方法
    在php 很少,请使用该限制很大,很少有很高。例如:这种技术可确保可以通过遍历XML树和使用儿童()方法()方法的XML树和切换名称空间来访问名称空间内的元素。
    编程 发布于2025-04-27
  • 如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    如何将多种用户类型(学生,老师和管理员)重定向到Firebase应用中的各自活动?
    Red: How to Redirect Multiple User Types to Respective ActivitiesUnderstanding the ProblemIn a Firebase-based voting app with three distinct user type...
    编程 发布于2025-04-27
  • 解决MySQL插入Emoji时出现的\\"字符串值错误\\"异常
    解决MySQL插入Emoji时出现的\\"字符串值错误\\"异常
    Resolving Incorrect String Value Exception When Inserting EmojiWhen attempting to insert a string containing emoji characters into a MySQL database us...
    编程 发布于2025-04-27
  • 我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    我可以将加密从McRypt迁移到OpenSSL,并使用OpenSSL迁移MCRYPT加密数据?
    将我的加密库从mcrypt升级到openssl 问题:是否可以将我的加密库从McRypt升级到OpenSSL?如果是这样,如何?答案:是的,可以将您的Encryption库从McRypt升级到OpenSSL。可以使用openssl。附加说明: [openssl_decrypt()函数要求iv参...
    编程 发布于2025-04-27
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-04-27
  • `console.log`显示修改后对象值异常的原因
    `console.log`显示修改后对象值异常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    编程 发布于2025-04-27
  • Python不会对超范围子串切片报错的原因
    Python不会对超范围子串切片报错的原因
    在python中用索引切片范围:二重性和空序列索引单个元素不同,该元素会引起错误,切片在序列的边界之外没有。这种行为源于索引和切片之间的基本差异。索引一个序列,例如“示例” [3],返回一个项目。但是,切片序列(例如“示例” [3:4])返回项目的子序列。索引不存在的元素时,例如“示例” [9] ...
    编程 发布于2025-04-27
  • 如何简化PHP中的JSON解析以获取多维阵列?
    如何简化PHP中的JSON解析以获取多维阵列?
    php 试图在PHP中解析JSON数据的JSON可能具有挑战性,尤其是在处理多维数组时。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    编程 发布于2025-04-27
  • 如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    如何将PANDAS DataFrame列转换为DateTime格式并按日期过滤?
    Transform Pandas DataFrame Column to DateTime FormatScenario:Data within a Pandas DataFrame often exists in various formats, including strings.使用时间数据时...
    编程 发布于2025-04-27
  • 人脸检测失败原因及解决方案:Error -215
    人脸检测失败原因及解决方案:Error -215
    错误处理:解决“ error:( - 215)!empty()in Function openCv in Function MultSiscale中的“检测”中的错误:在功能检测中。”当Face Cascade分类器(即面部检测至关重要的组件)未正确加载时,通常会出现此错误。要解决此问题,必须...
    编程 发布于2025-04-27

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3