⚡切图仔?你知道 V8 是如何执行 JS 代码的吗?

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: ⚡切图仔?你知道 V8 是如何执行 JS 代码的吗?

1.gif

📢 大家好,我是小丞同学,一名准大二的前端爱好者  📢 这篇文章将带你了解 V8 是如何执行 JS 代码的  📢 愿你忠于自己,热爱生活  引言

image.png

源代码首先通过解析器解析成 AST ,然后 AST 再通过解释器解释成最终的字节码


下面我们来聊聊解析器解析成 AST 的这个过程


首先我们先了解一下什么是 AST


🍉 1. 生成 AST

AST 中文名叫抽象语法树,它是源代码语法结构的一种抽象表示


它以树状的形式表现编程语言的语法结构,书上的每个节点都表示源代码中的一种结构


下面我们来一个例子看看 AST 是如何产生的

let name = 'ljc'

我们定义了一个 name 变量  解析器第一步要做的就是把这个语句拆分成最小的不可拆分的单元

image.png

生成 token 流,即语法单元成的数组

[
    {
        "type": "Keyword",
        "value": "let"
    },
    {
        "type": "Identifier",
        "value": "name"
    },
    {
        "type": "Punctuator",
        "value": "="
    },
    {
        "type": "String",
        "value": "ljc"
    },
    {
        "type": "Punctuator",
        "value": ";"
    }
]

第二步就是语法分析


将上一步的 token 数据,转为 AST,得到一个树状结构


因此 AST 也被称为抽象语法树


在生成 AST 的同时,V8 还会生成相关的作用域,作用域中存放相关变量


🍏 2. 生成字节码

在有了 AST 和作用域之后,就可以生成字节码了,字节码是介于AST 和机器码之间的一种代码,可以不需要将其转换成机器码后再执行,字节码可以理解为是机器码的一种抽象。Ignition 解释器除了可以快速生成没有优化的字节码外,还可以执行部分字节码。


那为什么需要生成字节码呢?直接转换为机器代码不是更好吗?


直接转换会带来内存占用过大的问题,因为如果抽象语法树全部生成机器代码,而机器代码相比于字节码,占用的内存要多的多

这是网上的一张对比图


image.png

image.png

某些 JavaScript 使用场景使用解释器更为合适,解析成字节码,有些没有必要的代码就可以不生产机器代码,这样可以尽可能的减少占用内存过大的问题 🍒 3. 执行代码及优化

image.png

在上一步生成的字节码,直接被解释器执行,在代码不断地运行过程中,解释器会收到很多可以用来优化代码的信息,比如变量的类型,哪些函数执行的频率较高,这些信息会被发生个编译器 TruboFan ,它会根据这些信息和字节码来编译出经过优化的机器代码。


运行时几个优化策略


函数只声明未被调用,不会被解析生成 AST

函数只被调用一次,字节码会直接被解释执行

函数被调用多次,可能会被标记为热点函数,可能会被编译成机器代码

关于热点函数


编译器 TurboFan 会将这些热点代码编译成更高效的机器代码储存起来,等到下次再执行时,会用现在的机器代码替换原来的字节码进行执行,这样就会大大的提示代码的执行效率。同时当 TurboFan 判断一段代码不再为热点代码的时候,会执行去优化的过程,把优化的机器码丢掉,然后执行过程回到解释器。


有时候解释器收集到的一些信息会是错误的,这就会导致 TurboFan 生成机器代码后,会被逆向还原成字节码


例如:当我们定义一个 sum 函数,在后面的多次调用中,它接收的两个参数我们都传的是整形,sum 函数被识别为热点函数,解释器将收集到的类型信息发送给编译器,编译器生成优化后的机器代码,此时当中的类型被定义为整型,在下次的调用中,直接执行机器代码。


而如果在下次的调用中,传入的参数是字符串型,机器代码不知道如何处理,就会返回给解释器解释执行


因此我们尽量不要把一个变量的类型变来变去,这样会对 V8 引擎带来一些影响,损失一定的性能


以上就是 V8 执行 JS 代码的具体流程


image.png

相关文章
|
14天前
|
JavaScript
短小精悍的js代码
【10月更文挑战第17天】
116 58
|
24天前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 来检查代码规范并自动格式化 Vue.js 代码。
【10月更文挑战第7天】随着前端开发技术的快速发展,代码规范和格式化工具变得尤为重要。本文介绍了如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 来检查代码规范并自动格式化 Vue.js 代码。通过安装和配置这两个工具,可以确保代码风格一致,提升团队协作效率和代码质量。
185 2
|
27天前
|
JavaScript 前端开发 内存技术
js文件的入口代码及需要入口代码的原因
js文件的入口代码及需要入口代码的原因
32 0
|
1天前
|
JavaScript
原生js炫酷随机抽奖中奖效果代码
原生js随机抽奖是一个炫酷的根据数据随机抽奖的代码,该网页可进行随机抽取一个数据,页面动画高科技、炫酷感觉的随机抽奖效果,简单好用,欢迎下载!
9 3
原生js炫酷随机抽奖中奖效果代码
|
6天前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤
随着前端开发技术的快速发展,代码规范和格式化工具变得尤为重要。本文介绍了如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码,包括安装插件、配置 ESLint 和 Prettier 以及 VSCode 设置的具体步骤。通过这些工具,可以显著提升编码效率和代码质量。
73 4
|
8天前
|
JSON 移动开发 数据格式
html5+css3+js移动端带歌词音乐播放器代码
音乐播放器特效是一款html5+css3+js制作的手机移动端音乐播放器代码,带歌词显示。包括支持单曲循环,歌词显示,歌曲搜索,音量控制,列表循环等功能。利用json获取音乐歌单和歌词,基于html5 audio属性手机音乐播放器代码。
46 6
|
4天前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码
随着前端开发技术的快速发展,代码规范和格式化工具变得尤为重要。本文介绍如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查代码规范并自动格式化 Vue.js 代码。通过安装和配置这些工具,可以确保代码风格一致,提高代码质量和可读性。
15 1
|
22天前
|
JavaScript 前端开发 开发者
如何在 VSCode 中使用 ESLint 和 Prettier 检查并自动格式化 Vue.js 代码,提升团队协作效率和代码质量。
【10月更文挑战第9天】随着前端开发技术的发展,代码规范和格式化工具变得至关重要。本文介绍如何在 VSCode 中使用 ESLint 和 Prettier 检查并自动格式化 Vue.js 代码,提升团队协作效率和代码质量。通过安装插件、配置 ESLint 和 Prettier,以及设置 VSCode,实现代码实时检查和格式化,确保代码风格一致。
18 2
|
23天前
|
JavaScript 前端开发 开发者
如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查并自动格式化 Vue.js 代码,提升代码质量和团队协作效率。
【10月更文挑战第8天】本文介绍了如何在 Visual Studio Code (VSCode) 中使用 ESLint 和 Prettier 检查并自动格式化 Vue.js 代码,提升代码质量和团队协作效率。通过安装 VSCode 插件、配置 ESLint 和 Prettier,实现代码规范检查和自动格式化,确保代码风格一致,提高可读性和维护性。
32 2
|
19天前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理、应用与代码演示
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理、应用与代码演示