javascript基础十一:JavaScript中执行上下文和执行栈是什么?

news2024/11/28 1:35:09

在这里插入图片描述
一、执行上下文

简单的来说,执行上下文是对Javascript代码执行环境的一种抽象概念,只要有Javascript代码运行,那么它就一定是运行在执行上下文中

执行上下文的类型分为三种:

  • 全局执行上下文:只有一个,浏览器中的全局对象就是 window对象,this 指向这个全局对象
  • 函数执行上下文:存在无数个,只有在函数被调用的时候才会被创建,每次调用函数都会创建一个新的执行上下文
  • Eval 函数执行上下文:指的是运行在 eval 函数中的代码,很少用而且不建议使用

下面给出全局上下文和函数上下文的例子:
在这里插入图片描述
紫色框住的部分为全局上下文,蓝色和橘色框起来的是不同的函数上下文。只有全局上下文(的变量)能被其他任何上下文访问

可以有任意多个函数上下文,每次调用函数创建一个新的上下文,会创建一个私有作用域,函数内部声明的任何变量都不能在当前函数作用域外部直接访问

二、生命周期

执行上下文的生命周期包括三个阶段:创建阶段 → 执行阶段 → 回收阶段

创建阶段做了三件事:

  • 确定 this 的值,也被称为 This Binding
  • LexicalEnvironment(词法环境) 组件被创建
  • VariableEnvironment(变量环境) 组件被创建

举个粟子

ExecutionContext = {  
  ThisBinding = <this value>,     // 确定this 
  LexicalEnvironment = { ... },   // 词法环境
  VariableEnvironment = { ... },  // 变量环境
}

This Binding
确定this的值我们前面讲到,this的值是在执行的时候才能确认,定义的时候不能确认

词法环境
词法环境有两个组成部分:

  • 全局环境:是一个没有外部环境的词法环境,其外部环境引用为null,有一个全局对象,this 的值指向这个全局对象
  • 函数环境:用户在函数中定义的变量被存储在环境记录中,包含了arguments 对象,外部环境的引用可以是全局环境,也可以是包含内部函数的外部函数环境

伪代码如下

GlobalExectionContext = {  // 全局执行上下文
  LexicalEnvironment: {       // 词法环境
    EnvironmentRecord: {     // 环境记录
      Type: "Object",           // 全局环境
      // 标识符绑定在这里 
      outer: <null>           // 对外部环境的引用
  }  
}

FunctionExectionContext = { // 函数执行上下文
  LexicalEnvironment: {     // 词法环境
    EnvironmentRecord: {    // 环境记录
      Type: "Declarative",      // 函数环境
      // 标识符绑定在这里      // 对外部环境的引用
      outer: <Global or outer function environment reference>  
  }  
}

变量环境
变量环境也是一个词法环境,因此它具有上面定义的词法环境的所有属性
在 ES6 中,词法环境和变量环境的区别在于前者用于存储函数声明和变量( let 和 const )绑定,而后者仅用于存储变量( var )绑定

举个粟子

let a = 20;  
const b = 30;  
var c;

function multiply(e, f) {  
 var g = 20;  
 return e * f * g;  
}

c = multiply(20, 30);

执行上下文如下:

GlobalExectionContext = {

  ThisBinding: <Global Object>,

  LexicalEnvironment: {  // 词法环境
    EnvironmentRecord: {  
      Type: "Object",  
      // 标识符绑定在这里  
      a: < uninitialized >,  
      b: < uninitialized >,  
      multiply: < func >  
    }  
    outer: <null>  
  },

  VariableEnvironment: {  // 变量环境
    EnvironmentRecord: {  
      Type: "Object",  
      // 标识符绑定在这里  
      c: undefined,  
    }  
    outer: <null>  
  }  
}

FunctionExectionContext = {  
   
  ThisBinding: <Global Object>,

  LexicalEnvironment: {  
    EnvironmentRecord: {  
      Type: "Declarative",  
      // 标识符绑定在这里  
      Arguments: {0: 20, 1: 30, length: 2},  
    },  
    outer: <GlobalLexicalEnvironment>  
  },

  VariableEnvironment: {  
    EnvironmentRecord: {  
      Type: "Declarative",  
      // 标识符绑定在这里  
      g: undefined  
    },  
    outer: <GlobalLexicalEnvironment>  
  }  
}

留意上面的代码,let和const定义的变量a和b在创建阶段没有被赋值,但var声明的变量从在创建阶段被赋值为undefined
这是因为,创建阶段,会在代码中扫描变量和函数声明,然后将函数声明存储在环境中

但变量会被初始化为undefined(var声明的情况下)和保持uninitialized(未初始化状态)(使用let和const声明的情况下)

这就是变量提升的实际原因

执行阶段

在这阶段,执行变量赋值、代码执行
如果 Javascript 引擎在源代码中声明的实际位置找不到变量的值,那么将为其分配 undefined 值

回收阶段
执行上下文出栈等待虚拟机回收执行上下文

二、执行栈

执行栈,也叫调用栈,具有 LIFO(后进先出)结构,用于存储在代码执行期间创建的所有执行上下文

在这里插入图片描述
当Javascript引擎开始执行你第一行脚本代码的时候,它就会创建一个全局执行上下文然后将它压到执行栈中

每当引擎碰到一个函数的时候,它就会创建一个函数执行上下文,然后将这个执行上下文压到执行栈中

引擎会执行位于执行栈栈顶的执行上下文(一般是函数执行上下文),当该函数执行结束后,对应的执行上下文就会被弹出,然后控制流程到达执行栈的下一个执行上下文

举个粟子:

let a = 'Hello World!';
function first() {
  console.log('Inside first function');
  second();
  console.log('Again inside first function');
}
function second() {
  console.log('Inside second function');
}
first();
console.log('Inside Global Execution Context');

在这里插入图片描述
简单分析一下流程:

  • 创建全局上下文请压入执行栈
  • first函数被调用,创建函数执行上下文并压入栈
  • 执行first函数过程遇到second函数,再创建一个函数执行上下文并压入栈
  • second函数执行完毕,对应的函数执行上下文被推出执行栈,执行下一个执行上下文first函数
  • first函数执行完毕,对应的函数执行上下文也被推出栈中,然后执行全局上下文
  • 所有代码执行完毕,全局上下文也会被推出栈中,程序结束

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

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

相关文章

基于MPC的自适应巡航控制(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Kyligence x 明道云|低代码平台助力中小企业实现存量背景下的创新增长

国内大部分制造企业在经历疫情后&#xff0c;终于迎来了市场端的消费需求的恢复和增长&#xff0c;但如何在激烈的竞争中以更少投入&#xff0c;获得更高回报&#xff0c;在市场上获得一席生存之地&#xff0c;成为了悬在众多企业头上的达摩克利斯之剑。在市场野蛮生长阶段时&a…

使用PYQT5和VTK实现一个六轴跟随的电路板转动动画效果

实现过程&#xff1a; 关于六轴&#xff1a; 线下有一个带有六轴姿态传感器的硬件设备&#xff0c;将采集到的三轴加速度和角速度的值每隔1秒通过串口发送给电脑&#xff0c;电脑上位机使用的是pyqt5&#xff0c;在python中调用serial模块进行串口数据的接收&#xff0c;接收…

专业是要选软工还是人工智能?

大家好&#xff0c;我是帅地。 在帅地的训练营里&#xff0c;也有不少 26 届的学员&#xff0c;不过大一即将过去&#xff0c;部分学校是到了大一后面或者大二才开始细分专业方向的&#xff0c;包括一些想要转专业的同学&#xff0c;也需要选择一个细分的方向&#xff0c;而且…

10:mysql----存储引擎--进阶篇

目录 1:MySQL体系结构 2:存储引擎简介 3:存储引擎特点 4:存储引擎选择 1:MySQL体系结构 连接层 : 最上层是一些客户端和链接服务&#xff0c;主要完成一些类似于连接处理、授权认证、及相关的安全方案。服务器也会为安全接入的每个客户端验证它所具有的操作权限。 服务层 :…

抽象轻松JavaScript

想象一样&#xff0c;现在有一个苹果&#xff0c;两个苹果&#xff0c;一箱苹果在你面前 看&#xff0c;上面的三种苹果&#xff0c;&#xff08;我写的是苹果就是苹果&#xff09; 语境1 例如你现在要搬运苹果&#xff01; 那么现在上面有苹果&#xff0c;一个&#xff0c;两…

阿里云的数据库架构如何设计,以实现高可用性和容灾性?

阿里云的数据库架构如何设计&#xff0c;以实现高可用性和容灾性&#xff1f;   在当今的数字化时代&#xff0c;数据库作为应用程序的核心组件之一&#xff0c;对于企业的正常运行至关重要。这篇文章将为您解析阿里云如何设计其数据库架构&#xff0c;以实现高可用性和容灾性…

加法器种类介绍

二进制加法器 二进制加法器接收加数A和B,以及进位Ci,输出和S,以及进位输出Co.二进制加法器的真值表如下&#xff1a; 逻辑表达式&#xff1a; S A ⊕ B ⊕ C i SA⊕B⊕C_i SA⊕B⊕Ci​ C o A B B C i A C i C_oABBC_iAC_i Co​ABBCi​ACi​ 从实现的角度&#xff0c;可以…

好兄弟,一天面了4家公司,堪称Offer收割机...

好兄弟一天面了4家公司&#xff0c;堪称Offer收割机… 面试感受 先说一个字 是真的 “ 累 ” 安排的太满的后果可能就是一天只吃一顿饭&#xff0c;一直奔波在路上 不扯这个了&#xff0c;给大家说说面试吧&#xff0c;我工作大概两年多的时间&#xff0c;大家可以参考下 在…

开关电源DCDC并联均流输出8V(XL4015)-2011年全国电赛题

2011年全国电赛题-开关电源模块并联供电系统&#xff0c;两路XL4015芯片做DCDC模块输出8V&#xff0c;采用主从均流法&#xff0c;可实现多种比例精确分配电流&#xff0c;效率在80%以上。 题目 设计并制作一个由两个额定输出功率均为 16W 的 8V DC/DC 模块构成的并联供电系统…

【事务】@Transactional 注解参数详解

文章目录 前言一、参数详解1.1、isolation&#xff08;事务隔离级别&#xff09;1.2、propagation&#xff08;事务传播机制&#xff09;1.3、readOnly&#xff08;事务读写性&#xff09;1.4、noRollbackFor 和 noRollbackForClassName&#xff08;遇到时不回滚&#xff09;1.…

PHPMySQL基础(四):模拟登录Login功能案例

PHP&MySQL基础&#xff08;一&#xff09;:创建数据库并通过PHP进行连接_长风沛雨的博客-CSDN博客 PHP&MySQL基础&#xff08;二&#xff09;:通过PHP对MySQL进行增、删、改、查_长风沛雨的博客-CSDN博客 PHP&MySQL基础&#xff08;三&#xff09;:处理查询SQL返…

敏捷指标: 评估计划的进展

作者 | Will Hayes, Patrick Place, and Keith Korzec ——卡耐基梅隆大学 度量标准有助于实现一个运作良好的系统&#xff0c;评判现有流程的绩效。在项目交付契约功能时能够对其性能进行监督。本文探讨了在一个复杂的信息物理系统的迭代、增量交付过程中&#xff0c;政府项目…

Django从Models 10分钟建立一套RestfulApi

简介 Django是一套完善而强大的web开发框架, 结合Django Restframework我们可以非常快的搭建一套后台的api, 该api主要特点: 标准的Restful接口, 支持增删改查 每个模型分列表和详情两种接口, 列表GET获取列表/POST新建,详情接口GET获取详情/PUT修改/DELETE删除所有接口自带权…

DJ4-5 基本分段存储管理方式

目录 4.5.1 分段式存储管理方式的引入 4.5.2 分段式存储管理的基本原理 一、分段 二、段表 三、地址变换机构 4.5.3 段的共享和保护 一、分页共享 二、分段共享 4.5.4 段页式存储管理 一、段页式存储管理的引入 二、段页式存储管理 三、地址变换机构 四、评价…

小明找前缀100000(假)

题目背景 小明最近上课天天睡觉&#xff0c;于是啥都不会。 一天&#xff0c;老师终于点兵点将点到他回答问题&#xff0c;你能帮他渡过难关吗&#xff1f; 现在老师给了小明 n 个由 0、1 构成的字符串&#xff0c;然后有 m 次询问&#xff0c; 每次询问给出一个由 0、1 构…

【医学图像】图像分割系列.3 (uncertainty)

介绍几篇使用不确定性引导的医学图像分割论文&#xff1a;UA-MT&#xff08;MICCAI2019&#xff09;&#xff0c;SSL4MIS&#xff08;MICCAI2021&#xff09;&#xff0c;UG-MCL&#xff08;AIIM2022&#xff09;. Uncertainty-aware Self-ensembling Model for Semi-supervise…

3-网络初识-协议

1.概念 协议&#xff0c;网络协议的简称&#xff0c;网络协议是网络通信&#xff08;即网络数据传输&#xff09;经过的所有网络设备都必须共同遵从的一组约定、规则。如怎么样建立连接、怎么样互相识别等。只有遵守这个约定&#xff0c;计算机之间才能相互通信交流。通常由三…

Android系统中的Binder通信机制分析(6)- Binder通信机制详解

声明 其实对于Android系统Binder通信的机制早就有分析的想法&#xff0c;记得2019年6、7月份Mr.Deng离职期间约定一起对其进行研究的&#xff0c;但因为我个人问题没能实施这个计划&#xff0c;留下些许遗憾…文中参考了很多书籍及博客内容&#xff0c;可能涉及的比较多先不具…

SER5 5500U 黑苹果系统安装教程

注意事项&#xff1a; 安装黑苹果系统需要一定的技术和操作经验&#xff0c;而且存在一定的风险&#xff0c;安装前请注意备硬盘内的数据&#xff0c;以免数据丢失&#xff0c;不推荐普通用户进行尝试&#xff0c;本系统及引导由黑果小兵独家制作&#xff0c;更多黑苹果教程百度…