JavaScript 进阶学习笔记

2021/12/2 JavaScript

# JavaScript 在浏览器是如何被执行的?

# 浏览器下载资源

域名经过解析变成ip地址(服务器地址),服务器就会返回一个index.html文件,浏览器解析html时会下载对应的资源。

# 浏览器内核

浏览器内核指的是浏览器的排版引擎(layout engine),又称浏览器引擎页面渲染引擎样版引擎

# 浏览器渲染过程

浏览器下载HTML文件之后进行解析,通过HTML解析器( HTML Parser) 和 CSS解析器( CSS Parser )对 HTML 和 CSS 进行解析,形成 DOM树(DOM Tree)和CSS规则 (CSS Tree),结合在一起生成一棵 渲染树(Render Tree),再通过布局引擎(Layout)对渲染树进行操作(比如不同设备的宽度问题)。有了最终的渲染树就会进行 绘制(Painting),最后进行展示(Display)。

在这个过程中,JS可以对DOM进行操作,会由JavaScript 引擎来对JS代码进行解析。

# JavaScript 引擎

JavaScript引擎会把JavaScript代码转换为机器可以执行的机器语言

# 浏览器引擎和 JS 引擎的关系

image-20211202173611546

# V8引擎

# V8引擎架构

V8引擎详细的解析执行过程 (opens new window)

image-20211202174329105

V8引擎对JavaScript源代码进行解析,进行词法分析(生成tokens,包含type,value等)和语法分析,然后生成 抽象语法树(AST),然后通过 字节码解释器(Ignition)将抽象语法树转换成 字节码(bytecode)(因为JS运行环境是不一定的,不同的环境可能拥有不同的CPU,能执行的机器指令是有区别的,所以转换成能跨平台的字节码,然后转换成汇编语言,最后再转换成不同平台的机器码)。而对于多次执行的JS代码,会通过优化编译器(TurboFan)来生成 优化后的机器码,直接进行执行,来提升性能。(而当函数执行操作不一致时,通过 动态反优化 ( Deoptimization) 重新转换成字节码,所以对应参数传值性能更高,如TS)。

image-20211202181114208

# V8引擎的解析图(官方)

内核(Blink)遇到 JS 会下载下来传递给 JS 引擎,Stream获取到源码并进行编码转换,然后 扫描器(Scanners)会进行词法分析和语法分析。

预解析(PreParser):有些代码不运行,没有必要转化成AST树,会简单对这些代码进行预解析。

# JS执行过程

# GlobalObject (GO)

在执行JS代码时,进行解析生成AST的阶段,会创建一个GlobalObject(比如全局的String,Date,Number,setTimeout以及全局var等)

在这个阶段,会把定义的全局对象进行赋值为undefined.

# 执行上下文栈

为了执行代码,V8引擎会有一个执行上下文栈(Execution Context Stack )(ECStack)(函数调用栈),所有的函数执行都要被加载到ECStack里面进行执行。

# 全局执行上下文

为了全局代码能够正常执行,需要创建全局执行上下文(Global Execution Context )(GEC),会把全局执行上下文 放到 执行上下文栈 里面执行。

# Variable Object(VO)

VO可以看作指向GO对象,开始执行代码时会在VO中进行查找,会对应在GO中进行查找替换。

# 全局代码执行过程(函数)

在编译过程中,在GO中普通的变量(如name)会赋值为undefined,而遇到函数时,也会生成一个属性,但不会赋值,而是另外创建一个内存空间来存储函数,会创建一个对象(函数对象),会保存一个父级作用域以及函数的执行体(代码块)。

所以,函数的作用域是在编译时就确定了,跟函数在哪里被调用无关

在执行遇到函数时,在VO中查询,对应在GO中找到这个函数,会找到对应的内存空间。会在 ECStack 里面创建一个 函数执行上下文FEC),在 FEC 里面存在一个 AO 活跃对象(Activation Object),会把函数里面的变量赋值为undefined

在函数执行时会在FEC里面的 VO+父级作用域中 查询,对应在AO+父级作用域中找到进行操作。

同时:当查找一个变量时,真实的查找路径时沿着作用域链来一层一层查找。

当函数完毕之后会函数执行上下文弹出栈,销毁掉FEC。

# 环境变量和记录

# 早期版本

# 新版

VO => VE

Last Updated: 2022/2/7下午10:20:47