浏览器工作原理与实践
李兵
前盛大创新院高级研究员
56402 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 46 讲
浏览器工作原理与实践
15
15
1.0x
00:00/00:00
登录|注册

14 | 编译器和解释器:V8是如何执行一段JavaScript代码的?

ESLint
Babel
解析(parse)
分词(tokenize)
每次运行时需要解释器动态解释和执行
经过编译器编译成二进制文件
编译器TurboFan编译热点代码为机器码
解释器Ignition解释执行字节码
字节码+JIT技术
字节码介于AST和机器码之间
AST的应用
AST生成过程
解释型语言
编译型语言
减少JavaScript文件的容量
避免大的内联脚本
提升单次脚本的执行速度
执行代码
生成字节码
生成抽象语法树(AST)和执行上下文
语言划分为编译型和解释型语言
机器不能直接理解代码
思考题:V8执行时间越久,执行效率越高
JavaScript的性能优化
V8执行一段JavaScript代码的流程
思考时间
编译器和解释器

该思维导图由 AI 生成,仅供参考

前面我们已经花了很多篇幅来介绍 JavaScript 是如何工作的,了解这些内容能帮助你从底层理解 JavaScript 的工作机制,从而能帮助你更好地理解和应用 JavaScript。
今天这篇文章我们就继续“向下”分析,站在 JavaScript 引擎 V8 的视角,来分析 JavaScript 代码是如何被执行的。
前端工具和框架的自身更新速度非常快,而且还不断有新的出现。要想追赶上前端工具和框架的更新速度,你就需要抓住那些本质的知识,然后才能更加轻松地理解这些上层应用。比如我们接下来要介绍的 V8 执行机制,能帮助你从底层了解 JavaScript,也能帮助你深入理解语言转换器 Babel、语法检查工具 ESLint、前端框架 Vue 和 React 的一些底层实现机制。因此,了解 V8 的编译流程能让你对语言以及相关工具有更加充分的认识。
要深入理解 V8 的工作原理,你需要搞清楚一些概念和原理,比如接下来我们要详细讲解的编译器(Compiler)、解释器(Interpreter)、抽象语法树(AST)、字节码(Bytecode)、即时编译器(JIT)等概念,都是你需要重点关注的。

编译器和解释器

之所以存在编译器和解释器,是因为机器不能直接理解我们所写的代码,所以在执行程序之前,需要将我们所写的代码“翻译”成机器能读懂的机器语言。按语言的执行流程,可以把语言划分为编译型语言和解释型语言。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

V8引擎是如何执行JavaScript代码的?本文深入解析了V8引擎执行JavaScript代码的内部工作原理。从编译器和解释器的角度出发,详细介绍了V8执行JavaScript代码的流程。文章首先解释了编译型语言和解释型语言的区别,然后重点分析了V8引擎的执行过程。通过讲解抽象语法树(AST)的生成和执行上下文的作用,以及解释器Ignition如何根据AST生成字节码并执行,读者能够深入了解V8引擎的内部工作原理。此外,文章还介绍了字节码的概念及其在内存占用方面的优势,以及V8引擎中的即时编译(JIT)技术。最后,文章延伸说明了优化JavaScript性能的一些策略,为读者提供了全面的技术视角。通过本文的阅读,读者能够全面了解V8引擎执行JavaScript代码的过程,对于想深入理解JavaScript底层执行机制的读者来说,是一篇很有价值的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《浏览器工作原理与实践》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(88)

  • 最新
  • 精选
  • 不将就
    重复看之前的文章,受益良多,在此表示感谢! 不过有几个疑问,老师有空的解答下哈! 问题一: 渲染进程里的input标签上传图片,通过与浏览器主进程通信,主进程读取硬磁盘图片数据返回给渲染进程,渲染进程里的js发起ajax请求,是通过浏览器主进程去调用网络进程发起请求,还是渲染进程可以直接调用网络进程发起请求? 问题二: 请求长时间处于pending状态或者脚本执行死循环,这时刷新或前进后退页面不响应,刷新或前进后退页面是属于浏览器主进程的UI交互行为,为什么渲染进程里的js引擎执行会影响到主进程? 问题三: function fn(){ var a =10 function f1(){ console.log(a) }; function f2(){ console.log('f2') }; f2(); }; fn(); 我在函数f2里打断点,当执行到函数f2时,chrome里显示Closure:{a:10},如果把这个原因解释为在fn函数里会预扫描f1函数,那我现在把fn2函数和调用都注释了,现在执行fn函数时不产生Closure,为什么就不预扫描f1函数了?这是为什么?

    作者回复: 第一个问题: xmlhttprequest 可以直接走网络进程,不需要浏览器进程介入 第二个问题: 因为前进或者后退也需要执行当前页面脚本啊,比如要执行beforeunload事件,执行的时候页面没响应了,所以前进后退也就失效了 第三个问题: 你把f2注释了,当执行fn函数时,照样会预扫描f1,照样会产生闭包,只不过当fn执行结束之后,闭包的内容没有外部引用,那么下次垃圾回收直接把比闭包的内容回收掉

    2019-09-05
    9
    86
  • 钟钟
    执行时间越长,执行效率越高。是因为更多的代码成为热点代码之后,转为了机器码来执行吗?

    作者回复: 是的

    2019-09-08
    9
    47
  • Rapheal
    老师,编译的基本单位是一段JS代码(内敛JS)或者一个JS文件吗(还是以当前调用栈将要执行函数为单位)?

    作者回复: 全局代码,或者函数 ! 比如下载完一个js文件,先编译这个js文件,但是js文件内定义的函数是不会编译的。 等调用到该函数的时候,Javascript引擎才会去编译该函数!

    2019-09-09
    7
    44
  • GY
    前面第7和第12讲,变量提升说js的执行过程,是有编译过程的,变量提升就发生在编译过程,经过编译后,会生成两部分内容,执行上下文和可执行代码,但是在这一讲中,却并没有编译过程,在AST生成后,解释器就开始执行生成字节码执行了,这几讲的内容有点互相冲突,那么详细的过程到底是怎样的呢 我在查看其它资料,出现了预编译这个名词,这个又怎么解释呢 希望能解答下

    作者回复: 你可以把JavaScript的编译看成了部分: 第一部分从一段JavaScript代码编译到字节码,然后解释器解释执行字节码! 第二部分深度编译,将活跃的字节码编译成二进制,然后直接执行二进制。 无论哪个阶段都需要编译。

    2019-09-27
    5
    11
  • Bazinga
    总结说:V8 依据 JavaScript 代码生成 AST 和执行上下文,再基于 AST 生成字节码,然后通过解释器执行字节码,通过编译器来优化编译字节码。但是第二节生成字节码那一段 说:解释器 Ignition 就登场了,它会根据 AST 生成字节码,并解释执行字节码。还有即时编译(JIT)技术那张图片,看起来也是先生成字节码 再经过解释器 。 所以字节码是解释器生成的吗?我都看懵了,求解答。

    作者回复: 流程是这样的: v8先生成ast! 然后ignition根据ast生成字节码。 在然后ignition解释执行字节码。 所以ignition生成了字节码并解释执行字节码。

    2019-11-28
    2
    9
  • westfall
    字节码最终也会转成机器码来执行的吧?因为最终都是cpu来执行,cpu只能执行机器码

    作者回复: 是的

    2019-10-23
    9
  • Marvin
    我理解,V8执行越久,被编译成机器码的热点代码就越多,所以整体执行效率就越高。如果是这样的话,那么V8内存占用也会越来越多,会面临的问题会和

    作者回复: 引入了字节码,就有弹性空间了,可以在内存和执行速度之间做调节。 相比之前的V8,将JS代码全部编译成字节码,这种模式就没有协商的空间了!

    2019-09-05
    2
    7
  • 小兵
    避免大的内联脚本,因为在解析 HTML 的过程中,解析和编译也会占用主线程;这句话可以理解为解析HTML代码的时候需要解析内联代码,而放到js文件的时候不需要吗? 另外思考题应该是执行越久,热点代码越多,即时编译的作用越大。

    作者回复: 只要是同步脚本都会阻塞,这里我可能没说清楚。 我的表达的以上是同步脚本尽量小,尽量能内联。 其它的尽量采用异步脚本,如使用aysnc和defer。

    2019-09-05
    7
    7
  • 李懂
    怎么都需要字节码文件,为啥,jsvaScript不像java一样先编译为字节码,这样执行效率不就高了么!

    作者回复: 你可以认为WebAssembly就是,WebAssembly经过TuboFan处理下就能执行了

    2019-09-05
    7
  • Angus
    V8执行越久,被编译成机器码的热点就越多,这些机器码帮助字节码可以直接执行而不用再使用解释器逐行执行,这相当于浏览器缓存,提高了执行性能。这些生成的机器码也会带来内存占用升高的问题,这里应该会有一个权衡措施吧,根据已占用的内存权衡如何判定是热点并生成机器码保存。

    作者回复: 是的,可以实现很多策略来权衡不同系统的情况

    2019-09-05
    2
    3
收起评论
显示
设置
留言
88
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部