浏览器如何执行JS
作为JS系列的第一篇,内容当然是浏览器如何执行一段JS啦。
首先通过浏览器篇我们可以得知,JS是在渲染进程里的JS引擎线程执行的。在此之后还要了解几个概念,编译器(Compiler)、解释器(Interpreter)、抽象语法树(AST)、字节码(Bytecode)、即时编译(JIT)
编译器和解释器
之所以存在编译器和解释器,是因为机器不能直接理解我们所写的代码,所以在执行程序之前,需要将我们所写的代码“翻译”成机器能读懂的机器语言。按语言的执行流程,可以把语言划分为编译型语言和解释型语言。
编译型语言
编译型语言在程序执行之前,需要经过编译器的编译过程,并且编译之后会直接保留机器能读懂的二进制文件,这样每次运行程序时,都可以直接运行该二进制文件,而不需要再次重新编译了
解释型语言
在每次运行时都需要通过解释器对程序进行动态解释和执行。比如 Python、JavaScript 等都属于解释型语言。

编译器和解释器进行'翻译'的流程
V8执行代码流程

1.通过词法分析,语法分析生成抽象语法树(AST)和执行上下文
- 第一阶段是分词(tokenize),又称为词法分析,其作用是将一行行的源码拆解成一个个 token。所谓 token,指的是语法上不可能再分的、最小的单个字符或字符串。
- 第二阶段是解析(parse),又称为语法分析,其作用是将上一步生成的 token 数据,根据语法规则转为 AST。如果源码符合语法规则,这一步就会顺利完成。但如果源码存在语法错误,这一步就会终止,并抛出一个“语法错误”。
2.根据AST生成字节码
有了 AST 和执行上下文后,那接下来的第二步,解释器 Ignition 就登场了,它会根据 AST 生成字节码,并解释执行字节码。
字节码就是介于 AST 和机器码之间的一种代码。但是与特定类型的机器码无关,字节码需要通过解释器将其转换为机器码后才能执行。
3.执行代码
如果有一段第一次执行的字节码,解释器 Ignition 会逐条解释执行。解释器 Ignition 除了负责生成字节码之外,它还有另外一个作用,就是解释执行字节码。在 Ignition 执行字节码的过程中,如果发现有热点代码(HotSpot),比如一段代码被重复执行多次,这种就称为热点代码,那么后台的编译器 TurboFan 就会把该段热点的字节码编译为高效的机器码,然后当再次执行这段被优化的代码时,只需要执行编译后的机器码就可以了,这样就大大提升了代码的执行效率。
V8 的解释器和编译器的取名也很有意思。解释器 Ignition 是点火器的意思,编译器 TurboFan 是涡轮增压的意思,寓意着代码启动时通过点火器慢慢发动,一旦启动,涡轮增压介入,其执行效率随着执行时间越来越高效率,因为热点代码都被编译器 TurboFan 转换了机器码,直接执行机器码就省去了字节码“翻译”为机器码的过程。其实字节码配合解释器和编译器是最近一段时间很火的技术,比如 Java 和 Python 的虚拟机也都是基于这种技术实现的,我们把这种技术称为即时编译(JIT)
相关问题
为什么V8代码执行时间越久,执行效率越高?
因为即时编译(JIT)技术的存在,解释器执行字节码的过程中,如果发现有热点代码(HotSpot),那么后台的编译器 TurboFan 就会把该段热点的字节码编译为高效的机器码,然后当再次执行这段被优化的代码时,只需要执行编译后的机器码就可以了,这样就省去了省去了字节码“翻译”为机器码的过程大大提升了代码的执行效率。
参考:浏览器原理与实践
浏览器如何执行JS的更多相关文章
- 在CMD下启动vmware、Xshell连接虚拟机以及控制Chrome浏览器自动执行js登录校园网
标题有点长,主要是写个bat出来玩玩, (1)不用每次都手动关闭mysql服务(我不想把它设为手动启动,有强迫症) (2)然后希望每次vmware能自动连上虚拟机 (3)以及每次Xshell都能自动启 ...
- l浏览器执行JS
浏览器执行JS 浏览器分成两部分:渲染引擎和JS引擎 渲染引擎:用来解析HTML与CSS,俗称内核,比如chrome浏览器的blink,老版本的webkit JS引擎:俗称JS解析器.用来读取网页中的 ...
- AngularJs中,如何在render完成之后,执行Js脚本
AngularJs是Google开源的前端JS框架.使用AngularJs, 我们能够容易地.健壮的开发出类似于Gmail一样的单页Web应用.AngularJs这个新兴的MVC前端框架,具有以下特点 ...
- 浏览器内核与js引擎
摘要: 面试一个大公司的时候问到了一个问题,让我谈谈主要的浏览器内核以及他们的特点,当时并没有详细的回答,回来之后自己在网上找了找资料,总结了下分享给大家. 简介: 在维基百科上是这样介绍浏览器内核的 ...
- A标签执行JS脚本
A标签执行JS脚本 分类: Web2012-12-25 22:48 1368人阅读 评论(0) 收藏 举报 前言 A标签是html中常用的标签,它与button按钮是实现页面跳转的两种最常用的方式,经 ...
- java中执行js代码
要在java中执行js代码,首先明白,java不支持浏览器本身的方法.支持自定义的js方法,否则会报错 先新建一个js文件:jsss.js 内容如下: function aa(a,b){ return ...
- 从浏览器多进程到JS单线程,JS运行机制的一次系统梳理
前言 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正. ----------超长文+多图预警,需要花费不少时间.---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏 ...
- 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理
前言 来源:https://dailc.github.io/2018/01/21/js_singlethread_eventloop.html 见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会 ...
- python selenium-webdriver 执行js (八)
使用python selenium 做自动化测试的时候其实我基本没有使用过执行js,只是在后来使用selenium来爬虫的时候使用到了,所以我在这里也就拿出来简单的介绍一下如何执行js. execut ...
随机推荐
- kill杀死进程
[root@queen ~]# kill 选项 %进程号 选项与参数: -l :这个是L 的小写,列出kill 能够使用的signal - :重新读取一次参数的设定档(类似reload) - :代表与 ...
- [cpp]C++中的析构函数
C++中的析构函数 简介 析构函数(Destructors),是对象的成员函数,没有返回值也没有参数,且一个类只有一个析构函数,当对象被销毁的时候调用,被销毁通常有这么几个情况. 函数执行结束 程序执 ...
- async/await剖析
async/await剖析 JavaScript是单线程的,为了避免同步阻塞可能会带来的一些负面影响,引入了异步非阻塞机制,而对于异步执行的解决方案从最早的回调函数,到ES6的Promise对象以及G ...
- robot framework使用小结(四)
robot framework可以采用读excel表这种形式实现数据分离,本文没有实现批量读取excel表内容(还不会),后续有必要就学习哈再更新~~~ 新建测试案例baidu05, 右键项目名rob ...
- 入门大数据---Spark_Streaming整合Kafka
一.版本说明 Spark 针对 Kafka 的不同版本,提供了两套整合方案:spark-streaming-kafka-0-8 和 spark-streaming-kafka-0-10,其主要区别如下 ...
- Python实用笔记 (8)高级特性——迭代
如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 比如dict就可以迭代: >>> d = {'a ...
- 前端基础:”天龙八步“细说浏览器输入URL后发生了什么
参考:https://www.xuecaijie.com/it/157.html#1Q64p5DeC8dKFF 本文摘要: 1.DNS域名解析: 2.建立TCP连接: 3.发送HTTP请求: 4.服务 ...
- JavaScript基础初始时期分支(018)
Init-Time Branching初始时期分支是一种用做优化的模式.如果某些条件在程序启动后就不再改变,那么我们就只需要在初始时期检查一次就可以了,而不是在每次 需要用到这些条件的时候都检查一次. ...
- 使用Tensorflow对模型进行量化
本文旨在将迁移学习训练好的模型基于tensorflow工具进行量化. 环境配置及迁移学习部分可参考博文[https://www.cnblogs.com/hayley111/p/12887853.htm ...
- Idea自带插件Groovy无法创建和启动
前言 如果现在有人要开始完全重写 Java,那么 Groovy 就像是 Java 2.0.Groovy 并没有取代 Java,而是作为 Java 的补充,它提供了更简单.更灵活的语法,可以在运行时动态 ...