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

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: ⚡切图仔?你知道 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

相关文章
|
2天前
|
JavaScript
网站内容禁止复制的js代码
网站内容禁止复制的js代码
|
8天前
|
缓存 JavaScript 前端开发
js和html代码一定要分离吗
JavaScript(JS)和HTML代码的分离虽非绝对必要,但通常被推荐
|
11天前
|
移动开发 JavaScript 安全
总有一款适合您分享78个JS相册代码
本文分享了78款JS相册代码,包括3D相册旋转木马、图片悬浮效果、倾斜图片幻灯片切换等特效,适用于各种图片展示场景。无论您需要哪种样式,都能在这里找到满意的解决方案。快来挑选吧!参考链接:[点击这里](https://www.vipwb.com/sitemap.xml)。
23 4
|
12天前
|
JavaScript
分享一款520表白节JS代码
今天给大家分享一款JS表白源码 js会随 随机颜色心形跟随鼠标互动520表白节女神表白利器! 修改的话就搜索:LOVEh 就能找到这个英文了。
7 0
分享一款520表白节JS代码
|
19天前
|
JSON JavaScript 前端开发
如何使用代码注释:关于JavaScript与TypeScript
TSDoc是一种标准化TypeScript代码文档注释的规范,使不同工具能无干扰地提取内容。它包括多种标记,如@alpha、@beta等发布阶段标记;@decorator、@deprecated等功能标记;@defaultValue、@eventProperty等描述标记;@example、@experimental等示例与实验性标记;@inheritDoc、@internal等引用与内部标记;@label、@link等链接标记;@override、@sealed等修饰符标记;以及@packageDocumentation、@param、
25 5
|
17天前
|
Web App开发 JavaScript 前端开发
JavaScript基础知识-使用Firefox进行代码的调试(Debug)
关于如何使用Firefox浏览器进行JavaScript代码调试的基础知识介绍。
29 0
|
20天前
|
开发者 图形学 C#
深度解密:Unity游戏开发中的动画艺术——Mecanim状态机如何让游戏角色栩栩如生:从基础设置到高级状态切换的全面指南,助你打造流畅自然的游戏动画体验
【8月更文挑战第31天】Unity动画系统是游戏开发的关键部分,尤其适用于复杂角色动画。本文通过具体案例讲解Mecanim动画状态机的使用方法及原理。我们创建一个游戏角色并设计行走、奔跑和攻击动画,详细介绍动画状态机设置及脚本控制。首先导入动画资源并添加Animator组件,然后创建Animator Controller并设置状态间的转换条件。通过编写C#脚本(如PlayerMovement)控制动画状态切换,实现基于玩家输入的动画过渡。此方法不仅适用于游戏角色,还可用于任何需动态动画响应的对象,增强游戏的真实感与互动性。
45 0
|
20天前
|
Android开发 iOS开发 C#
Xamarin:用C#打造跨平台移动应用的终极利器——从零开始构建你的第一个iOS与Android通用App,体验前所未有的高效与便捷开发之旅
【8月更文挑战第31天】Xamarin 是一个强大的框架,允许开发者使用单一的 C# 代码库构建高性能的原生移动应用,支持 iOS、Android 和 Windows 平台。作为微软的一部分,Xamarin 充分利用了 .NET 框架的强大功能,提供了丰富的 API 和工具集,简化了跨平台移动应用开发。本文通过一个简单的示例应用介绍了如何使用 Xamarin.Forms 快速创建跨平台应用,包括设置开发环境、定义用户界面和实现按钮点击事件处理逻辑。这个示例展示了 Xamarin.Forms 的基本功能,帮助开发者提高开发效率并实现一致的用户体验。
42 0
|
21天前
|
JavaScript 开发者 UED
Vue.js 错误处理与调试:跟上技术潮流,摆脱开发困扰,成为代码大神不是梦!
【8月更文挑战第30天】在 Vue.js 开发中,错误处理与调试至关重要。本文将对比 Vue 的全局错误捕获机制 `Vue.config.errorHandler` 和组件内 `watch` 监听数据变化的方式,并介绍 Vue 开发者工具、控制台打印 (`console.log`) 以及代码断点 (`debugger`) 等调试方法。此外,还将探讨如何通过自定义错误页面提升用户体验。通过这些技巧的对比,帮助开发者灵活选择适合的策略,确保应用稳定性和开发效率。
38 0
|
21天前
|
JavaScript 前端开发
揭秘Vue.js组件魔法:如何轻松驾驭前端代码,让维护变得轻而易举?
【8月更文挑战第30天】本文探讨了如何利用Vue.js的组件化开发提升前端代码的可维护性。组件化开发将复杂页面拆分为独立、可复用的组件,提高开发效率和代码可维护性。Vue.js支持全局及局部组件注册,并提供了多种组件间通信方式如props、事件等。通过示例展示了组件定义、数据传递及复用组合的方法,强调了组件化开发在实际项目中的重要性。
13 0