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

yizhihongxing

我们来详细讲解一下“详解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日

相关文章

  • 浅谈js多维数组和hash数组定义和使用

    针对“浅谈js多维数组和hash数组定义和使用”的话题,我来进行详细讲解。 多维数组 JavaScript中的多维数组,其实就是由多个一维数组组成的数组。我们可以使用一维数组来构建多维数组,比如: const multiArr = [ // 二维数组 [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; const threeDArr = […

    JavaScript 2023年5月27日
    00
  • 最通俗易懂的javascript变量提升详解

    最通俗易懂的Javascript变量提升详解 什么是变量提升 变量提升是Javascript的一种默认行为,指在代码执行期间,Javascript将变量和函数声明提升到它们所在作用域的顶部,以便能够访问它们。这意味着可以在声明之前使用变量或函数。 变量提升的情况 Javascript中有两种类型的声明:变量声明和函数声明。这两种声明在变量提升时会被解析并移动…

    JavaScript 2023年6月11日
    00
  • 用nodejs实现json和jsonp服务的方法

    以下是详细讲解“用nodejs实现json和jsonp服务的方法”的完整攻略。 什么是JSON和JSONP JSON (JavaScript Object Notation)是一种轻量级的数据交换格式,易于读写、快速解析和生成,通常用于客户端与服务器之间的数据传输。 JSONP (JSON with Padding)是一种跨域通信技术,它利用了标签的跨域特性…

    JavaScript 2023年5月27日
    00
  • Javascript中的数据类型之旅

    好的。首先,“JavaScript中的数据类型之旅”是一篇介绍JavaScript数据类型的文章,可以帮助初学者更好地了解JavaScript数据类型。下面是我为你准备的完整攻略: JavaScript中的数据类型之旅 1. 基本数据类型 JavaScript中有6种基本数据类型:String(字符串)、Number(数字)、Boolean(布尔)、Null…

    JavaScript 2023年5月27日
    00
  • js输出数据精确到小数点后n位代码

    下面是 js 输出数据精确到小数点后 n 位代码的完整攻略。 方式一:Number.prototype.toFixed() 方法 Number.prototype.toFixed() 方法可以将一个数四舍五入为指定小数位数的数字。它的基本语法如下: number.toFixed(digits) 其中,number 是要转换的数字,digits 是要保留的小数…

    JavaScript 2023年5月28日
    00
  • 在页面加载之后执行JavaScript

    在页面加载之后执行JavaScript通常包括以下两种情况: 在DOMContentLoaded事件触发之后执行JavaScript代码 DOMContentLoaded事件在文档结构已经加载完成,但是加载的所有资源(例如图片)还没有完成的时候触发。可以使用addEventListener()方法监听DOMContentLoaded事件,并在回调函数中执行J…

    JavaScript 2023年6月11日
    00
  • HTML5中的websocket实现直播功能

    下面是关于“HTML5中的WebSocket实现直播功能”的完整攻略: 一、什么是WebSocketWebSocket是一个协议,它提供了在单个TCP连接上进行全双工通信的能力,并能够让服务器主动向客户端推送数据。相比于HTTP,WebSocket的一个明显优点就是它的实时性更高,因为不需要为了发送数据而频繁地建立和关闭TCP连接。 二、创建WebSocke…

    JavaScript 2023年6月11日
    00
  • JS 创建对象的模式实例小结

    下面是关于“JS 创建对象的模式实例小结”的完整攻略,其中包含两个示例说明: JS 创建对象的模式实例小结 在 JavaScript 中,创建对象有多种模式,不同的模式适用于不同的场景和需求。本文将对常见的四种创建对象的模式做一个简单介绍和小结,方便读者选择合适的模式进行对象创建。 一、工厂模式 工厂模式通过工厂方法创建对象,将创建对象的过程封装在一个函数中…

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