03- javascript的运行原理

article/2025/6/28 17:04:16

文章目录

  • 1. V8引擎
    • 执行原理与架构(了解)
  • 2. javascript 执行过程
    • 2.1 初始化全局对象
    • 2.2 执行上下文栈
  • 3. 全局代码的执行
  • 4. 函数代码的执行
  • 5. 作用域和作用链

1. V8引擎

先来了解一下V8引擎:

在这里插入图片描述

简单来说,V8引擎就是在做javascript代码转换成机器语言,从而被cpu识别继而运行的工作。

执行原理与架构(了解)

在这里插入图片描述
V8引擎本身的源码非常复杂,大概有超过100w行C++代码,通过了解它的架构,我们可以知道它是如何对)vaScript执行的:

  • Parse:将javascript代码转换成AST抽象语法树,因为解释器并不直接认识js代码;

    • 如果函数没有被调用,那么就不会被转成AST
  • lgnition:是一个解释器,会将AST转换成字节码;

    • 同时会收集TurboFan需要的类型信息(比如函数参数的类型信息,有了类型才能进行真实的运算)
    • 如果函数只执行一次,那么将直接解释执行字节码
  • TurboFan:是一个编译器,可以将AST转换成CPU直接能运行的机器码;

    • 如果一个函数被多次调用,那么将会被标记为热点函数,那么就会经过TurboFan编译成优化的机器码,提高代码的执行性能;
    • 但是,机器码实际上也会被还原成字节码,这是因为如果后续执行过程中类型发生了变化,之前优化的机器码并不能正确的运算,就会逆向的转成字节码

在这里插入图片描述

2. javascript 执行过程

假设现在有段这样的代码,它应该是怎样执行的呢?
在这里插入图片描述
我们先来了解一下相关的基础知识!

2.1 初始化全局对象

  • 首先,js 在执行代码前,会创建一个全局对象:Global Object
    • 该对象 所有的作用域都可以访问;
    • 里面还会包含DateArrayNumbersetTimeoutsetInterval等;
    • 其中还有一个属性指向window

在这里插入图片描述

2.2 执行上下文栈

js 引擎内部有一个执行上下文栈(Excution Context Stack,简称ECS),是用于执行代码的调用栈。

  • 那么现在要执行的是谁呢?是全局的代码块:

    • 全局的代码块在执行前会创建一个Global Excution Context(GEC)
    • GEC会被放到ECS中执行
  • GEC被放到ECS中包含两部分内容:

    • 第一部分:在代码执行前,在parser转成AST的过程中,会将全局定义的变量、函数等加入到Global Object中,但并不会赋值;(这个过程也叫做变量的作用域提升)
    • 在代码执行中,对变量赋值,或者执行其他的函数;

3. 全局代码的执行

先来认识一下VO对象

  • 每个执行上下文都会关联一个VO(Variable Object,变量对象),变量和函数声明会被添加到这个VO对象中;
  • 当全局代码被执行的时候,VO就是GO对象了。

❗️❗️❗️问题来了!全局代码如何被执行呢?

执行前:
在这里插入图片描述
执行后:
在这里插入图片描述
现在更改代码为:
在这里插入图片描述

那就又有一个问题:函数代码如何执行呢?

4. 函数代码的执行

  • 执行代码遇到函数体时,就会根据函数体创建一个函数体上下文(Functional Excution Context),并且压入到ECS中;
  • 当进入函数体执行代码时,就会创建一个AO(Activation Obejct)
  • 这个AO会使用arguments作为初始化,并且初始值是传入的参数;
  • 这个AO对象会作为该函数体的执行上下文的VO来存放变量的初始化

在这里插入图片描述

执行函数上下文之后:
在这里插入图片描述
之后,函数执行上下文将会被压出栈外:
在这里插入图片描述

❗️在函数作用域中可能遇到这样的情况:

在这里插入图片描述

message变量的声明存在于全局作用域,但在局部作用域进行了调用,那局部作用域又是怎么找到全距作用与中的变量呢?

这就涉及到了javascript的作用域和作用链!

5. 作用域和作用链

在这里插入图片描述

上面说到,但我们进入一个执行上下文时,执行上下文会关联一个VO对象,其实,同时它也会关联一个 作用域链(Scope Chain)

  • 作用域链是一个对象列表,用于表示变量标识符的求值;
  • 当进入一个执行上下文时,这个作用域链就会被创建,并且根据代码类型,添加一系列的对象

http://www.hkcw.cn/article/HWWCTqDhIF.shtml

相关文章

三菱PLC编译程序提示无法与PLC通讯的设置

点击工具 下拉菜单到最下端 点击选项 转换(编译)中执行RUN中写入 前去掉勾选 点确定

nssctf第一题[SWPUCTF 2021 新生赛]re1

题目如上: 下载附件得到了一个可执行文件, 双击运行, 由于是逆向题,先放到ida中按f5,看一下伪码, 解读代码:strcpy(Str2, “{34sy_r3v3rs3}”);将字符串{34sy_r3v3rs3}赋给Str2; scanf(“%s”…

day17 leetcode-hot100-34(链表13)

23. 合并 K 个升序链表 - 力扣(LeetCode) 1.数组排序 思路 (1)将全部的节点存储到数组中 (2)对数组进行排序 (3)最后创建一个全新的链表 具体代码 /*** Definition for singly…

对抗攻击 Adversarial Attack

目录 对抗攻击的简介: 怎么攻击? 快速梯度符号法 白箱攻击和黑箱攻击: 攻击方式: 防御 被动防御 主动防御 对抗攻击的简介: 在输入的图片上加一点杂讯(一般人的肉眼看不见但是会影响机器&#xff0…

comfyui利用 SkyReels-V2直接生成长视频本地部署问题总结 2 :寻找丢失的model 和工作流中 get set 方法的应用

comfyui利用 SkyReels-V2直接生成长视频本地部署问题总结 2 寻找丢失的model 和工作流中 get set 方法的应用 第一:寻找丢失的model 在上一文章 安装完 自定义节点ComfyUI-WanVideoWrapper 后 我们打开实列 工作流。wanvideo_skyreels_diffusion_forcing_extensio…

Java内存模型与互斥锁

1. Java内存模型:解决可见性和有序性问题 1.1. 内存模型 内存模型的概念: 内存模型是一个抽象的概念,它描述了计算机内存的组织和访问方式。在编程中,内存模型是编译器和硬件设计者用来优化代码性能和正确性的一种工具。 内存…

Java如何读取CSV文件并将数据放入对象中详解

Java如何读取CSV文件并将数据放入对象中详解 CSV(Comma-Separated Values)文件是一种常见的数据存储格式,广泛应用于数据交换、日志记录和表格数据处理。在Java开发中,读取CSV文件并将数据映射到对象中是常见的需求。本文将详细介…

LazyOwn RedTeam/APT 框架是第一个具有人工智能驱动的 CC 的 RedTeam 框架

一、软件介绍 文末提供程序和源码下载 LazyOwn RedTeam/APT 框架是第一个具有人工智能驱动的 C&C 的 RedTeam 框架,具有隐藏活动的 rootkit、与 Windows/Linux/Mac OSX 兼容的不可检测的可塑植入物,以及自配置后门。凭借其 Web 界面和强大的…

Java学习——day2(Servlet 基础编程)

文章目录 1. 什么是 Servlet?2. Servlet 的生命周期2.1 init()2.2 service()2.3 destroy() 3. 创建 Servlet 类4. Servlet 配置方式4.1 创建步骤4.2 重新构建并启动项目4.3 启动Tomcat 5. 总结 1. 什么是 Servlet? Servlet 是 Java Web 中用于处理客户端…

Aop + 注解实现数据字典类型转换 EasyExcel导出

Aop 注解 实现数据字典类型转换 文章目录 Aop 注解 实现数据字典类型转换一、基础方式✅字典转换简介👉实现步骤✅ 1. 定义自定义注解Dict ✅ 2. 定义查询字典项的两个方法✅ 3. 定义Aop拦截我们查询的方法✅ 4. VO映射类✅ 5. Controller层✅ 6. serviceImpl✅ 7. …

力扣热题100之对称二叉树

题目 给你一个二叉树的根节点 root , 检查它是否轴对称。 代码 方法一:递归 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left …

链式前向星图解

e[idx] b; 边之终点 ne[idx] h[a]; 谓之头插之边 h[a] idx ; 谓之指针更新 注意:上述以a为开头的一条链上的结点,在物理上都是a的邻接点,相邻的边用idx来标明序号,相邻的边之间有映射。 链式前向星的遍历 假设顶点 u 的邻接表…

MybatisPlus(含自定义SQL、@RequiredArgsConstructor、静态工具类Db)

大家在日常开发中应该能发现,单表的CRUD功能代码重复度很高,也没有什么难度。而这部分代码量往往比较大,开发起来比较费时。 因此,目前企业中都会使用一些组件来简化或省略单表的CRUD开发工作。目前在国内使用较多的一个组件就是…

R语言基础| 创建数据集

在R语言中,有多种数据类型,用以存储和处理数据。每种数据类型都有其特定的用途和操作函数,使得R语言在处理各种数据分析任务时非常灵活和强大: 向量(Vector): 向量是R语言中最基本的数据类型,它…

UE特效Niagara性能分析

开启Niagara调试器 开启显示概览 界面显示 🟩 上方绿色面板:Niagara DebugHud 这是 HUD(调试视图) 模式下的性能统计显示,内容如下: 项目含义SystemFilter: ShockWave_01当前选中的 Niagara 粒子系统名称…

MySQL——事务

目录 问题 什么是事务 为什么会有事务 事务版本支持 事务提交方式 事务常见操作 事务隔离级别 查看与设置隔离性 事务四种隔离级别 读未提交 读提交 不可重复读 串行化 一致性 理解隔离性 4个隐藏字段 undo日志 MVCC Read View RR 与 RC 本质区别 问题…

Vue-3-前端框架Vue基础入门之VSCode开发环境配置和Tomcat部署Vue项目

文章目录 1 安装配置VSCode1.1 安装中文语言插件1.2 主题颜色1.3 禁用自动更新1.4 开启代码提示设置1.5 安装open in browser插件2 安装配置nodejs2.1 配置环境变量2.2 npm与maven的区别2.3 使用npm避坑3 创建Vue项目3.1 两种创建方式3.2 package.json3.3 安装新的依赖3.4 运行…

Webpack依赖

Webpack到底怎么对我们的项目进行打包捏? 在webpack处理应用程序时,会根据命令或者配置文件找到入口文件 从入口开始,会生成一个依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(.js、css文件、图片、字体…

关于找不到符号,符号变量log的问题的解决方案

创建时间:06月02日 1、问题描述 最近在学习鱼皮的AI超级智能体项目过程中,遇到如下错误: java: 找不到符号符号: 变量 log位置: 类 com.liucc.aiagent.app.LoveApp2、排查思路 网上的常见解决思路主要是检查lombok插件是否安装、Enable…