【JavaScript】执行栈和执行上下文

1. 执行上下文(Execution Context)

执行上下文是 JavaScript 中代码执行的环境的抽象概念,它包含了代码运行时所需的所有信息,比如变量的值、函数的引用等。

每当 JavaScript 代码执行前,都会创建一个执行上下文,并将其添加到执行栈中。执行上下文负责代码的执行和管理作用域。

JavaScript 中有三种执行上下文类型(环境)。

  • 全局执行上下文:这是默认或者说基础的上下文,任何不在函数内部的代码都在全局上下文中。他会执行两件事,创建一个全局的 window 对象(浏览器的情况下),并且设置 this 的值等于这个全局对象。
  • 函数执行上下文:每当一个函数被调用时,都会为该函数创建一个新的上下文。每个函数都有它自己的执行上下文,不过是在函数被调用时创建的。函数上下文可以有任意多个。每当一个新的执行上下文被创建,它会按定义的顺序执行一系列步骤。
  • Eval 函数执行上下文:执行在 eval 函数内部的代码也会有它属于自己的执行上下文。

执行上下文包含三个重要的属性:

  • 变量对象(Variable Object):包含变量、函数声明和形参等。
  • 作用域链(Scope Chain):用于解析标识符的链表。
  • this 指向:指向函数执行时的上下文对象。

JavaScript 运行时首先会进入全局环境,对应会生成全局上下文。程序代码中基本都会存在函数,那么调用函数,就会进入函数执行环境,对应就会生成该函数的执行下文。

由于代码中会声明多个函数,对应的函数执行上下文也会存在多个。在JavaScript中,通过栈的存取方式来管理执行上下文,我们可称其为执行栈,或函数调用栈(Call Stack)。

const foo = function (i) {console.log(b)  // undefinedconsole.log(c)  // [Function: c]let a = 'hello'let b = function privateB() {}function c(){}
}
foo(10)// 1. 创建上下文阶段// vo 里面确定的东西:
// 1. 函数的形参(并赋值)
// 2. 函数的 arguments 对象(并赋值)
// 3. 确定普通字面量形式的函数声明(并赋值)
// 3. 变量声明、函数表达式声明(未赋值)// 将执行上下文看做是一个对象
// fooExecutionContext = {// vo = {//     i:  10,//     arguments: {0: 10, length: 1},//     c: 指向 c 那个函数,//     a: undefined,//     b: undefined// },// this,// scope
// }// 2. 执行代码阶段
fooExecutionContext = {vo = {i:  10,arguments: {0: 10, length: 1},c: 指向 c 那个函数,a: 'hello',b: privateB},this,scope
}

2. 栈(Stack)

执行栈是一个后进先出(LIFO)的数据结构,用于存储执行上下文。当 JavaScript 代码执行时,会创建执行上下文,并将其推入执行栈的顶部。当函数执行完成后,对应的执行上下文将从栈顶弹出,控制权返回到上一个执行上下文。

执行栈(函数调用栈)

理解完栈的存取方式,我们接着分析 JavaScript 中如何通过栈来管理多个执行上下文。

程序执行会先创建全局执行上下文,所以栈底都是全局执行上下文;而栈顶是正在执行函数的执行上下文。

执行上下文可存在多个,虽然没有明确的数量限制,但如果超出栈分配的空间,会造成堆栈溢出。常见于递归调用,没有终止条件造成死循环的场景。

  • 当脚本要调用一个函数时,解析器把该函数添加到栈中并且执行这个函数。
  • 任何被这个函数调用的函数会进一步添加到调用栈中,并且运行到它们被上个程序调用的位置。
  • 当函数运行结束后,解释器将它从堆栈中取出,并在主代码列表中继续执行代码。
  • 如果栈占用的空间比分配给它的空间还大,那么则会导致“栈溢出”错误。

3. 执行上下文生命周期

执行上下文的生命周期包括以下几个阶段:

  • 创建阶段(Creation Phase):在此阶段,JavaScript 引擎会创建执行上下文。在全局上下文中,这一阶段发生在代码执行前;在函数上下文中,这一阶段发生在函数被调用时。
    • 初始化变量对象(Variable Object / VO)
      • 确定函数形参并赋值
      • 函数环境初始化创建arguments对象并赋值
      • 确定普通字面量形式的函数声明并赋值
      • 变量声明,函数表达式声明(未赋值)
    • 建立作用域链(Scope Chain)(在声明定义的地方确定)
    • 确定 this 的指向(this 由调用者确定)。
  • 执行阶段(Execution Phase):在此阶段,JavaScript 引擎会按照代码的顺序执行相应的代码,并为变量赋值、函数调用等。在执行阶段中,JavaScript 引擎会根据作用域链解析变量和函数标识符,并执行相应的代码逻辑。
  • 销毁阶段(Deletion Phase):在函数执行完成后或全局代码执行完成后,对应的执行上下文会被销毁。JavaScript 引擎会从执行栈中弹出该执行上下文,并释放相关的内存资源。
(function () {console.log(typeof foo);console.log(typeof bar);var foo = "Hello";var bar = function A() {return "World";}function foo() {return "good";}console.log(foo, typeof foo);
})()
// 1. 创建上下文阶段
// exeutionContext = {
//     vo: {
//         foo: 指向 foo 函数,
//         // 已有 foo 不会创建 foo 变量了
//         bar: undefined
//     },
//     this,
//     scope
// }
// 2. 执行代码
exeutionContext = {vo: {foo: "Hello",// 已有 foo 不会创建 foo 变量了bar: function A},this,scope
}console.log(typeof foo);  // function
console.log(typeof bar);  // undefined
var foo = "Hello";
var bar = function A() {return "World";
}function foo() {return "good";
}console.log(foo, typeof foo); //hello, string

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/833348.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简单聊下 Vue 3.0 和 React 18 框架有什么区别

Vue3 vs React 18:前端框架比较 随着Vue3和React 18的相继发布,前端开发领域再次迎来了技术革新的热潮。这两款框架各自迭代升级,不仅优化了原有特性,还引入了许多新概念,使得开发者在构建现代Web应用时拥有更多选择。…

C# winform 连接mysql数据库(navicat)

1.解决方案资源管理器->右键->管理NuGet程序包->搜索, 安装Mysql.Data 2.解决方案资源管理器->右键->添加->引用->浏览-> C:\Program Files (x86)\MySQL\MySQL Installer for Windows ->选择->MySql.Data.dll 3.解决方案资源管理器…

深入剖析Tomcat(七) 日志记录器

在看原书第六章之前,一直觉得Tomcat记日志的架构可能是个“有点东西”的东西。在看了第六章之后呢,额… 就这?不甘心的我又翻了翻logback与新版tomcat的源码,额…,日志架构原来也没那么神秘。本篇文章先过一遍原书内容…

Github 2024-05-07 开源项目日报 Tp10

根据Github Trendings的统计,今日(2024-05-07统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量TypeScript项目4Jupyter Notebook项目2Python项目1Batchfile项目1非开发语言项目1Java项目1HTML项目1C#项目1从零开始构建你喜爱的技术 创建周期…

使用 Maximo REST API 创建 Object Structure

接前面的文章&#xff0c;今天通过编写Python脚本的方式使用 Maximo REST API 创建Object Structure。 创建 object structure 这里创建一个新的 Work Order Object Structure&#xff0c;命名为 MXAPIWO123。 import requestsurl "<maximo url>/api/os/mxintob…

k8s 资源文件参数介绍

Kubernetes资源文件yaml参数介绍 yaml 介绍 yaml 是一个类似 XML、JSON 的标记性语言。它强调以数据为中心&#xff0c;并不是以标识语言为重点例如 SpringBoot 的配置文件 application.yml 也是一个 yaml 格式的文件 语法格式 通过缩进表示层级关系不能使用tab进行缩进&am…

金三银四面试题(二十五):策略模式知多少?

什么是策略模式 策略模式&#xff08;Strategy Pattern&#xff09;是一种行为型设计模式&#xff0c;旨在定义一系列算法&#xff0c;将每个算法封装到一个独立的类中&#xff0c;使它们可以互换。策略模式让算法的变化独立于使用它们的客户端&#xff0c;使得客户端可以根据…

二叉搜索树相关

二叉搜索树 定义&#xff1a;对二叉搜索树的一些操作基本结构Insert操作Find操作Erase操作 InOrder遍历二叉树操作模拟字典模拟统计次数 定义&#xff1a; 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树:若它的左子树不为空&a…

【记录 | Markdown语法】LaTeX数学公式

目录 Markdown语法基本运算符小数分数比大小括号特殊符号几何集合 Markdown语法 在Markdown中&#xff0c;LaTeX数学公式的编写遵循LaTeX语法&#xff0c;下面展示一些基本的LaTeX数学公式的用法和使用效果。 如果公式中包含特殊字符&#xff0c;需要使用反斜杠 \ 进行转义。 …

.Wormhole勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

导言&#xff1a; 随着信息技术的飞速发展&#xff0c;网络安全问题愈发凸显其重要性。近年来&#xff0c;勒索病毒成为了网络安全领域的一大难题&#xff0c;而其中的.Wormhole勒索病毒更是以其独特的传播方式和强大的破坏力引起了广泛关注。本文将详细介绍.Wormhole勒索病毒…

MacOS快速安装FFmpeg,并使用FFmpeg转换视频

前言&#xff1a;目前正在接入flv视频流&#xff0c;但是没有一个合适的flv视频流地址。网上提供的flv也都不是H264AAC&#xff08;一种视频和音频编解码器组合&#xff09;&#xff0c;所以想通过fmpeg来将flv文件转换为H264AAC。 一、MacOS环境 博主的MacOS环境&#xff08;…

初始C++(一)

目录 前言&#xff1a; 命名空间&#xff1a; 总结&#xff1a; 前言&#xff1a; C语言学好了&#xff0c;现在当然要进阶了&#xff0c;那么就是从C开始。 C兼容C&#xff0c;支持其中90%的语法。可能有很多同学听说过C#&#xff0c;C#和C没有关系&#xff0c;是微软研究出…

Mintegral引领短剧行业新风尚:广告变现策略助力出海应用高效增长

短剧&#xff0c;一颗正在冉冉升起的新星&#xff0c;如今成为了影视行业的新风口。《2023短剧行业研究报告》显示&#xff0c;2023年短剧市场规模达到373.9亿元&#xff0c;同比增长267.65%&#xff0c;预计2024年将超过500亿元。近年来&#xff0c;政策出台、供需促进及应用出…

什么是Facebook付费广告营销?

Facebook作为全球最大的社交平台之一&#xff0c;成为了跨境卖家不可或缺的营销阵地。它不仅拥有庞大的用户基数&#xff0c;还提供了丰富的广告工具和社群互动功能&#xff0c;让商家能够精准触达目标市场&#xff0c;提升品牌影响力。云衔科技通过Facebook付费广告营销的专业…

ODOO17数据库安全策略一(ODOO17 Database Security Policy I)

ODOO17作为ERP软件&#xff0c;其核心优势在于数据安全。凭借强大的原生安全机制及灵活的配置&#xff0c;确保数据安全无忧&#xff1a; ODOO17, as an ERP software, boasts its significant advantage in exceptional data security performance. It effectively ensures wo…

DirClass

DirClass 通过分析&#xff0c;发现当接收到DirClass远控指令后&#xff0c;样本将返回指定目录的目录信息&#xff0c;返回数据中的远控指令为0x2。 相关代码截图如下&#xff1a; DelDir 通过分析&#xff0c;发现当接收到DelDir远控指令后&#xff0c;样本将删除指定目录…

CMS-设计文档

CMS-设计文档 一. 身份审批模块1.1 表设计1.2 实体类设计1.3 接口设计1.3.1 查询-所有-分页欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中…

2024暨南大学校赛热身赛解析

文章目录 Uzi 的真身D 基站建设 Uzi 的真身 分析&#xff1a;本来想使用动态规划算法的&#xff0c;但是由于数据计算过大&#xff0c;导致超时 正确的思想&#xff1a;直接线性遍历字符串&#xff0c;分别统计字符“j”的个数&#xff0c;后面对于统计字符“z”和字符“h” 的…

Elasticsearch安装步骤

引言 Elasticsearch是一个基于Lucene构建的开源、分布式、RESTful搜索和分析引擎。它设计用于云计算中&#xff0c;能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。Elasticsearch为所有类型的数据提供近乎实时的搜索和分析。无论…

flutter中固定底部按钮,防止键盘弹出时按钮跟随上移

当我们想要将底部按钮固定在底部&#xff0c;我们只需在Widget中的Scaffold里面加一句 resizeToAvoidBottomInset: false, // 设置为false&#xff0c;固定页面不会因为键盘弹出而移动 效果图如下