详解JavaScript中的执行上下文及调用堆栈

我们来详细讲解一下“详解JavaScript中的执行上下文及调用堆栈”的攻略。

什么是执行上下文

当 JavaScript 代码执行一段可执行代码时,会创建对应的执行上下文。执行上下文可以理解为是当前 JavaScript 代码的执行环境或者说是当前代码执行时的上下文环境,它包含了当前执行代码所需的所有变量、函数、参数等信息。如果把生活中的场景来理解,执行上下文就相当于一个人在进行某个行动的情境,不同的情境会导致这个人采取不同的行动。

执行上下文的类型

在 JavaScript 中,一共有 3 种不同类型的执行上下文:

  1. 全局执行上下文:默认情况下,JavaScript 代码会在全局环境中被执行,此时就会创建一个全局执行上下文。
  2. 函数执行上下文:当函数被调用时,就会创建一个对应该函数的执行上下文。
  3. Eval 函数执行上下文:执行 eval 函数时,会创建一个对应该函数的执行上下文。

执行上下文的创建过程

当 JavaScript 代码开始执行时,首先会创建一个全局执行上下文。随后,当函数被调用时,就会依次按照下面的步骤创建函数执行上下文:

  1. 创建函数的 AO 对象(Activation Object),该对象包含了函数内部声明的变量、函数等信息;
  2. 创建作用域链(Scope Chain),该作用域链指向外部环境的变量对象;
  3. 确定 this 的指向。

同时,一旦执行上下文被创建完毕,就会被推入到调用堆栈(Call Stack)中。

调用堆栈

调用堆栈(Call Stack)是一种数据结构,它类似于一个箱子,被用来管理在执行上下文中代码的执行顺序。每当创建一个新的执行上下文时,就会被推入调用堆栈的顶部,当该执行上下文执行完毕后,就会从调用堆栈中弹出并清除。

示例1:全局执行上下文

我们来看一个示例,如下所示:

var a = 'Hello, World!';
function foo(){
    console.log(a);
}
foo();

在以上代码中,当 JavaScript 解释器开始执行该代码时,会首先创建一个全局执行上下文。随后,在全局执行上下文中,会先定义变量 a,并给其赋值 'Hello, World!'。接下来,会定义函数 foo,但是由于 JavaScript 并不会立刻执行函数,所以在执行 foo 之前,全局执行上下文将一直存在于调用堆栈的顶部。

当执行到 foo 函数时,在函数 foo 自己的执行上下文中也会创建 AO 对象,此时 AO 对象中并不包含变量 a,而是因为 foo 函数被定义在全局的作用域内,所以它可以访问到全局作用域中的变量 a。因此,在函数 foo 的作用域链中,会把全局作用域对象也加入进去,从而顺利地访问到了 a 这个变量。最终的输出结果就是 'Hello, World!'。

示例2:嵌套函数调用

我们来看另一个示例,如下所示:

function outer() {
    inner();
    console.log('outer function');
};
function inner() {
    console.log('inner function');
};
outer();

在以上代码中,当执行到 outer 函数时,会创建 outer 的执行上下文,并将其推入调用堆栈中,接着调用 inner 函数。在调用 inner 函数时,会创建 inner 的执行上下文,并将其推入堆栈中。此时,调用堆栈的顶部是 inner 函数的执行上下文,而 outer 函数的执行上下文位于其下方。

当执行完 inner 函数后,该执行上下文会从调用堆栈中弹出并被销毁,此时调用堆栈的顶部变成了 outer 函数的执行上下文,最终输出结果为 'inner function' 和 'outer function'。

通过以上两个示例,我们可以更加清晰地理解 JavaScript 中的执行上下文及调用堆栈。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解JavaScript中的执行上下文及调用堆栈 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • Bootstrap表单组件教程详解

    Bootstrap表单组件教程详解 Bootstrap是目前最为流行的前端框架之一,它提供了大量的样式和组件的封装,其中表单组件是网站开发中不可或缺的一部分。本文将为大家详细讲解Bootstrap表单组件的使用方法和常见问题。 基础表单组件 Bootstrap提供了包括输入框、单选框、复选框、下拉框等多种常用表单组件。 输入框 普通输入框 <div c…

    JavaScript 2023年6月10日
    00
  • JavaScript 参数中的数组展开 [译]

    文章“JavaScript 参数中的数组展开 [译]”介绍了JavaScript的一个很有用的语法特性:展开运算符(spread operator)。在函数参数中使用展开运算符可以方便地将数组或对象中的内容“展开”成独立的元素,方便使用。本文将对这一语法进行详细讲解。 什么是展开运算符? 展开运算符用符号“…”表示,它可以将一个数组或者类数组对象中的所有…

    JavaScript 2023年5月27日
    00
  • 关于 byval 与 byref 的区别分析总结

    关于 ByVal 与 ByRef 的区别分析总结 在 VBA 中,在声明函数或过程时,我们需要指定参数的传递方式,通常有两种方式:ByVal 和 ByRef。这两种方式的区别在于,ByVal 传递参数的值,而 ByRef 传递参数的引用地址。下面我们来详细讲解这两种方式的区别。 ByVal 的用法 在 VBA 中,ByVal 是指传递参数的值。也就是说,当我…

    JavaScript 2023年6月11日
    00
  • IE event.srcElement和FF event.target 功能比较

    当我们在JavaScript中处理web事件时,在不同的浏览器中可能会遇到不同的事件对象,其中包含用于获取目标元素的不同属性。 在IE中,事件对象提供了名为srcElement的属性,可以利用它去获取事件的目标元素。 而在Firefox等基于Gecko内核的浏览器中,事件对象提供了名为target的属性,同样可以获取事件的目标元素。 以下是两个简单的示例说明…

    JavaScript 2023年6月10日
    00
  • 和我一起学 Three.js【初级篇】:1. 搭建 3D 场景

    ? 本篇文章共 5572 字,最近更新于 2023 年 04 月 19 日。 0. 系列文章合集 本系列第 6,7,8 章节支持在我的个人公众号「前端乱步」内付费观看,将在全平台文章「点赞数」+「评论数」 >= 500(第 6 章), 1000(第 7,8 章) 时分别解锁发布。 《和我一起学 Three.js【初级篇】:0. 总论》 ? 您当前在这里…

    JavaScript 2023年4月20日
    00
  • js设置cookie过期当前时间减去一秒相当于立即过期

    设置Cookie的过期时间可以通过在Cookie中添加一个用于标识过期时间的Expires属性来实现。通常情况下,Expires属性的值可以是时间戳,表示Cookie的过期时间是基于指定的时间来计算。但如果我们需要相对于当前时间来设置Cookie的过期时间,那么就需要进行一些计算。 具体实现方法是:将当前时间的时间戳减去1秒的时间戳,然后将其转换为UTC格式…

    JavaScript 2023年5月27日
    00
  • Javascript Global decodeURIComponent() 函数

    以下是关于JavaScript Global对象中decodeURIComponent()函数的完整攻略,包括两个示例说明。 JavaScript Global对象中的decodeURIComponent()函数 JavaScript Global对象中的decodeURIComponent()函数用于解码一个码过的URI组件字符串。URIUniform R…

    JavaScript 2023年5月11日
    00
  • 如何使用JS console.log()技巧提高工作效率

    如何使用JS console.log()技巧提高工作效率 JavaScript 是前端开发必不可少的一门语言,而 console.log() 是 JS 里常用的调试工具。在这里,我们将从几个方面介绍如何使用 console.log() 技巧提高工作效率。 1. console.log()基本使用 console.log() 不仅仅只是打印一些信息。在开发过程…

    JavaScript 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部