• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

浏览器执行js原理-v8引擎

武飞扬头像
Ant spirit
帮助1


前言

了解浏览器运行JavaScript代码的原理,有助于我们开发中快速解决问题;本章主要讲解浏览器常见的内核、JavaScript引擎以及执行js代码的原理。


一、浏览器的内核与JavaScript引擎

1.认识常用浏览器的内核

排版引擎,也称浏览器引擎、页面渲染引擎或样式引擎

Gecko:早期被Netscape和Mozila Firefox浏览器使用;
Trident::微软开发,被IE4-IE11浏览器使用,Edge浏览器已经转向Blink;
Webkit::苹果基于KHTML开发的(开源),用于Safari,Google Chrome之前的版本也有使用;
Blink:是Webkit的一个分支,Google开发,目前用于Google Chrome、Opera、Edge等;

2.浏览器渲染过程

  1. 加载html,将html文件转成domTree
  2. 执行过程中,html解析的时候遇到了JavaScript标签,会停止解析html,而去加载和执行JavaScript代码
  3. 加载并解析css,生成Style Rules
  4. 将Style Rules 与 DOM Tree相结合
  5. 通过布局引擎形成Render Tree
  6. 绘制、展示

学新通

3.认识JavaScript引擎

为什么需要JavaScript引擎?
实际上高级编程语言都是需要转成机器指令来执行的,JavaScript也不例外。
我们所编写的JavaScript程序无论是在浏览器或者Node环境下,最终都是需要被CPU执行的;CPU只认识自己的指令集、即机器语言。所以我们需要JavaScript引擎帮助我们将JavaScript代码翻译成CPU可执行的指令。

常见的JavaScript引擎:

  • SpiderMonkey:第一款JavaScript引擎,由Brenden Eich(即JavaScript作者)
  • Chakra:微软开发,用于IE浏览器
  • JavaScriptCore:WebKit中的JavaScript引擎,Apple公司开发
  • V8:Google开发的强大JavaScript引擎,也帮助Google Chrome从众多浏览器中脱颖而出

4.浏览器内核与JavaScript引擎的关系

WebKit
WebCore负责HTML解析\布局\渲染等等相关工作
JavaScriptCore:解析和执行javasc代码

二、V8引擎

1.原理

我们来看一下官方对V8引擎的定义:

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

抽象语法树:https://astexplorer.net/

2.执行的细节

那么我们的JavaScript源码是如何被解析(Parse过程)的呢?

  1. Blink将源码交给V8引擎,Stream获取到源码并且进行编码转换;
  2. Scanner会进行词法分析(lexical analysis),词法分析会将代码转换成tokens;
  3. 接下来tokens会被转换成AST树,经过Parser和PreParser:
  4. Parser就是直接将tokens转成AST树架构;
    PreParser称之为预解析,为什么需要预解析呢?
    这是因为并不是所有的JavaScript代码,在一开始时就会被执行。那么对所有的JavaScript代码进行解析,必然会影响网页的运行效率;
    所以V8引擎就实现了Lazy Parsing(延迟解析)的方案,它的作用是将不必要的函数进行预解析,也就是只解析暂时需要的内容,而对函数的全量解析是在函数被调用时才会进行;
    比如我们在一个函数outer内部定义了另外一个函数inner,那么inner函数就会进行预解析;
  5. 生成AST树后,会被Ignition转成字节码(bytecode),之后的过程就是代码的执行过程(后续会详细分析)。

三、js执行原理

流程图:

学新通

以下面这段代码举例

var name = 'ant'
function foo(){
	var name = 'foo'
	console.log(name)
}
var num1 = 20;
var num2 = 30
var result = num1   num2;
console.log(result);

1.代码被解析

  • v8引擎内部会帮助我们创建一个对象(Global Object window就是全局);
  • 找变量声明,将变量声明作为GO对象的属性名,值赋予undifined
  • 找全局里的函数声明,将函数名作为GO对象的属性名,值赋予函数体
    学新通
// 1.代码被解析,v8引擎内部会帮助我们创建一个对象
//伪代码
globalObject = {
	Array: '类',
	String: "类",
	Date: '类',    
	setTimeout: '类',
	window: globalObject,
	num1: undefined,
	num2: undefined,
	result: undefined
}
  1. 运行代码
    Js引擎内部有一个执行上下文栈(Execution Context Stack,简称ECS),它是用于执行代码的调用栈。
    • 为了全局代码能够正常执行,需要创建全局执行上下文栈(Global execution context)
      GEC会 被放入到ECS中 执行;

      • 第一部分:在代码执行前,在parser转成AST的过程中,会将全局定义的变量、函数等加入到GlobalObject中,但是并不会赋值;这个过程也称之为变量的作用域提升(hoisting)
      • 第二部分:在代码执行中,对变量赋值,或者执行其他的函数;
    • 在执行的过程中执行到一个函数时,就会根据函数体创建一个函数执行上下文(Functional Execution Context,简称FEC),并且压入到EC Stack中。

      • 第一部分:在解析函数成为AST树结构时,会创建一个Activation Object(AO):
        AO中包含形参、arguments、函数定义和指向函数对象、定义的变量;
      • 第二部分:作用域链:由VO(在函数中就是AO对象)和父级VO组成,查找时会从里到外一层层查找;
      • 第三部分:this绑定的值:这个后面再单独写一篇讲吧!
        学新通
  2. 运行完成
    ESC中执行过的函数AO会弹出栈(销毁AO)

提示:此文章仅为个人总结,若有错误请批评指正,欢迎大家共同探讨!

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgbeacj
系列文章
更多 icon
同类精品
更多 icon
继续加载