前端进阶JS运行原理

news/2024/11/24 11:37:53/

JS运行原理

深入了解V8引擎原理

浏览器内核是由两部分组成的,以webkit为例:

  • WebCore:负责HTML解析、布局、渲染等等相关的工作;
  • JavaScriptCore:解析、执行JavaScript代码;

image-20230224183949294

官方对V8引擎的定义:

  • V8是用C ++编写的Google开源高性能JavaScript和WebAssembly引擎,它用于Chrome和Node.js等
  • 它实现ECMAScript和WebAssembly,并在Windows 7或更高版本,macOS 10.12+和使用x64,IA-32,ARM或MIPS处理
    器的Linux系统上运行。
  • V8可以独立运行,也可以嵌入到任何C ++应用程序中。

image-20230224184029597

V8引擎的架构很复杂 ,我们可以先了解它庞大引擎的一些模块

  • Parse模块会将JavaScript代码转换成AST(抽象语法树),这是因为解释器并不直接认识JavaScript代码
    • 如果函数没有被调用,那么是不会被转换成AST
    • Parse的V8官方文档:https://v8.dev/blog/scanner
  • Ignition是一个解释器,会将AST转换成ByteCode(字节码)
    • 同时会收集TurboFan优化所需要的信息(比如函数参数的类型信息,有了类型才能进行真实的运算)
    • 如果函数只调用一次,Ignition会解释执行ByteCode
    • Ignition的V8官方文档:https://v8.dev/blog/ignition-interpreter
  • TurboFan是一个编译器,可以将字节码编译为CPU可以直接执行的机器码
    • 如果一个函数被多次调用,那么就会被标记为热点函数,它会被TurboFan转换成优化的机器码,提高代码的执行性能
    • 机器码实际上也会被还原为ByteCode,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执
      行的是number类型,后来执行变成了string类型),之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码
    • TurboFan的V8官方文档:https://v8.dev/blog/turbofan-jit

V8架构解析图 来自官方

image-20230224184421893

image-20230224184508091

解析代码的步骤:

  1. 获得到代码之后 V8用流输入通过词法分析,分析成token
  2. 解析/预解析 来生成一个一个执行节点
  3. 生成 AST 树
  4. 转成字节码 如果有热点方法就会走turbofan编译器优化成机械码提升性能

全局代码执行过程

js引擎会在执行代码之前,会在堆内存中创建一个全局对象:Global Object(GO)

  • 该对象 所有的作用域(scope)都可以访问
  • 里面会包含Date、Array、String、Number、setTimeout、setInterval等等
  • 其中还有一个window属性指向自己

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

他执行的式全局代码块,它的作用就是:

  • 为了执行代码构建一个 Global Execution Context GEC 全局上下文
  • 将这个构建的上下文加入到执行栈中 也就是将 GEC 放入 ECS中

GEC被放入到ECS中里面包含两部分内容:

  • 在代码执行前,在parser转成AST的过程中,会将全局定义的变量、函数等加入到GlobalObject中,但是并不会赋值
  • 在代码执行中,对变量赋值,或者执行其他的函数;

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

全局上下文三个关键:

  • VO(go)
  • 作用域链
  • This

执行以下代码过程

    var message = "Global Message"function foo() {var message = "Foo Message"}var num1 = 10var num2 = 20var res = num1 + num2console.log(res);

全局代码执行前

image-20230225230158035

执行代码后

image-20230225231518618

函数代码执行过程

在执行的过程中执行到一个函数时,就会根据函数体创建一个函数执行上下文(Functional Execution Context,简称FEC),并且压入到EC Stack中

  • 当进入一个函数执行上下文时,会创建一个AO对象(Activation Object)
  • 这个AO对象会使用arguments作为初始化,并且初始值是传入的参数
  • 这个AO对象会作为执行上下文的VO来存放变量的初始化

如下函数执行过程

执行前

image-20230225231940365

执行后

image-20230225232044143

流程为:

  • 执行前创建FEC 也就是函数执行上下文
  • 创建 AO 对象 name为函数名
  • 创建作用域链
  • 生成函数对象存放代码
  • thisbing(暂无)
  • 之后从上到下执行代码
  • 执行完成后将name 变为 undefined

作用域和作用域链

当进入到一个执行上下文时,执行上下文也会关联一个作用域链(Scope Chain)

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

PS : 作用域会提升 在本身vo没有情况下 会去上层寻找,我们先输出后声明会输出undefined, 这里也印证了

作用域提升小练习

var n = 100
function foo(){n=200
}
foo()
console.log(n)

N =200

顺序内存查找图如下 :

  • 全局代码创建函数 找到 n放入到函数vo中 之后调用foo()
  • 在函数调用后找到GO中的n复制
  • 函数结束,之后输出n

image-20230226165920435

作用域链也是我们JS闭包的一个重点, js中闭包就是通过作用域链的方式来完成变量可以跨作用域访问的,为我们加快提升了开发的效率 也省去很多麻烦


http://www.ppmy.cn/news/28753.html

相关文章

一文带你搞懂Go语言函数选项模式,Go函数一等公民。

前言 通过这篇文章《为什么说Go的函数是”一等公民“》,我们了解到了什么是“一等公民”,以及都具备哪些特性,同时对函数的基本使用也更加深入。 本文重点介绍下Go设计模式之函数选项模式,它得益于Go的函数是“一等公民”&#…

Dbeaver连接Hive数据库操作指导

背景:由于工作需要,当前分析研究的数据基于Hadoop的Hive数据库中,且Hadoop服务端无权限进行操作且使用安全模式,在研究了Dbeaver、Squirrel和Hue三种连接Hive的工具,在无法绕开useKey认证的情况下,只能使用…

华为OD机试题,用 Java 解【两数之和绝对值最小】问题

最近更新的博客 华为OD机试题,用 Java 解【停车场车辆统计】问题华为OD机试题,用 Java 解【字符串变换最小字符串】问题华为OD机试题,用 Java 解【计算最大乘积】问题华为OD机试题,用 Java 解【DNA 序列】问题华为OD机试 - 组成最大数(Java) | 机试题算法思路 【2023】使…

【C语言】“qsort函数详解”与“使用冒泡思想模拟使用qsort”

✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨ 文章目录✨✨✨✨如果文章对你有帮助记得点赞收藏关注哦!!✨✨✨✨qsort的介绍:一、qsort函数的使用✨比较int类型数据比较字符型数据比较结构体数据冒泡思想…

华为OD机试 - 回文字符串(Java JS Python)

题目描述 如果一个字符串正读和反渎都一样(大小写敏感),则称它为一个「回文串」,例如: leVel是一个「回文串」,因为它的正读和反读都是leVel;同理a也是「回文串」art不是一个「回文串」,因为它的反读tra与正读不同Level不是一个「回文串」,因为它的反读leveL与正读不…

【MySQL之SQL语法篇】系统学习MySQL,从应用SQL语法到底层知识讲解,这将是你见过最完成的知识体系

文章目录一、数据管理技术的三个阶段二、SQL语句学习1. DCL数据控制语言1.1 创建用户1.2 修改用户名1.3 修改密码1.4 删除用户1.5 授权1.6 查看权限1.7 回收权限2. DDL数据定义语言2.1 操作数据库2.2 操作数据表2.3 操作数据3. DQL数据查询语言基本语法3.1 单表查询3.1.1选择表…

XXL-JOB

XXL-JOB介绍 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 官网:https://www.xuxueli.com/xxl-job/ 文档:分布式任务调度…

【面试题】当面试官问 Vue2与Vue3的区别,你该怎么回答?

大厂面试题分享 面试题库后端面试题库 (面试必备) 推荐:★★★★★地址:前端面试题库被问到 《vue2 与 vue3 的区别》应该怎么回答Vue 内部根据功能可以被分为三个大的模块:响应性 reactivite、运行时 runtime、编辑器…