JavaScript运行环境

48 阅读5分钟

浏览器工作原理

JavaScript是一门编程语言

编程语言发展历史:

机器语言: 1000100111011000 ,一些机器指令;

汇编语言: mov ax,bx,一些汇编指令;

高级语言: C、C++、Java、 JavaScript、 Python;

计算机它本身是不认识这些高级语言的,所以我们的代码最终还是需要被转换成机器指令

浏览器工作原理

image.png

认识浏览器的内核(浏览器的排版引擎)

不同的浏览器由不同的内核组成

Gecko :早期被Netscape和Mozilla Firefox浏览器浏览器使用; Trident :微软开发,被IE4~E11浏览器使用,但是Edge浏览器已经转向Blink ; Webkit :苹果基于KHTML开发、开源的,用于Safari ,Google Chrome之前也在使用; Blink :是Webkit的一个分支, Google开发,目前应用于Google Chrome、Edge、 Opera等;

排版引擎( layout engine ) ,也称为浏览器引擎( browser engine )、页面渲染引擎( rendering engine )或样版引擎

浏览器渲染过程

HTML解析的时候遇到了JavaScript标签,会停止解析HTML ,而去加载和执行JavaScript代码

JavaScript代码由JavaScript引擎来执行

image.png

JavaScript引擎

认识JavaScript引擎

💡
  1. 为什么需要JavaScript引擎呢?

高级的编程语言都是需要转成最终的机器指令来执行的 事实上我们编写的JavaScript无论交给浏览器或者Node执行,最后都是需要被CPU执行的 但是CPU只认识自己的指令集,实际上是机器语言,才能被CPU所执行 所以我们需要JavaScript引擎帮助我们将JavaScript代码翻译成CPU指令来执行

💡
  1. 比较常见的JavaScript引擎有哪些呢?
  • SpiderMonkey :第一款JavaScript引擎 ,由Brendan Eich开发(也就是JavaScript作者)
  • Chakra :微软开发,用于IE浏览器;
  • JavaScriptCore :WebKit中的JavaScript引擎,Apple公司开发;
  • V8 :Google开发的强大JavaScript引擎,也帮助Chrome从众多浏览器中脱颖而出……

浏览器内核和JS引擎的关系

💡

WebKit由两部分组成:

  • WebCore :负责HTML解析、布局、渲染等等相关的工作;
  • JavaScriptCore :解析、执行JavaScript代码;

在小程序中编写的JavaScript代码就是被JSCore执行的

image.png

V8引擎的原理

定义:

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

v8引擎架构图:

image.png

image.png

💡

Parse(解析) : 词法分析(tokens)和语法分析

Parse模块会将JavaScript代码转换成AST (抽象语法树) , 这是因为解释器并不直接认识JavaScript代码

如果函数没有被调用,那么是不会被转换成AST的(会进行PreParser预解析)

转成AST:AST explorer

💡

Ignition(解释器):将AST转换成ByteCode (字节码)

字节码 (好处 :跨平台 )→ 汇编代码 → 机器指令 (只出现一次)

Ignition → TurboFan 收集优化所需信息,例如标记热函数(出现频率高),提高性能

💡

TurboFan(编译器) :可以将字节码编译为CPU可以直接执行的机器码

如果一个函数被多次调用,那么就会被标记为热点函数,那么就会经过TurboFan转换成优化的机器码,提高代码的执行性能;

但是,机器码实际上也会被还原为ByteCode ,这是因为如果后续执行函数的过程中,类型发生了变化(比如sum函数原来执行的是number类型,后来执行变成了string类型), 之前优化的机器码并不能正确的处理运算,就会逆向的转换成字节码

Deoptimization 反向优化 ⇒ ts(类型约束)运行性能相对较高

image.png

JavaScript内存管理

认识内存管理

不管什么样的编程语言,在代码的执行过程中都是需要给它分配内存的,不同的是某些编程语言需要我们自己手动的管理内存某些编程语言会可以自动帮助我们管理内存

💡

不管以什么样的方式来管理内存,内存的管理都会有如下的生命周期

  • 第一步:分配申请你需要的内存(申请);
  • 第二步:使用分配的内存(存放一些东西,比如对象等);
  • 第三步:不需要使用时,对其进行释放
💡

不同的编程语言对于第一步和第三步会有不同的实现:

  • 手动管理内存:比如C、C++,包括早期的OC,都是需要手动来管理内存的申请和释放的(malloc和free函数);
  • 自动管理内存:比如Java、JavaScript、Python、Swift、Dart等,它们有自动帮助我们管理内存;

JS的内存管理

  • JS对于基本数据类型内存的分配会在执行时,直接在栈空间进行分配;
  • JS对于复杂数据类型内存的分配会在堆内存中开辟一块空间,并且将这块空间的指针返回值变量引用

JS的垃圾回收(Garbage Collection,GC)

对于那些不再使用的对象,我们都称之为是垃圾,它需要被回收,以释放更多的内存空间;

而我们的语言运行环境,比如Java的运行环境JVM,JavaScript的运行环境js引擎都会内存 垃圾回收器

常见的GC算法(引用计数、标记清除)

💡

引用计数:

  • 当一个对象有一个引用指向它时,那么这个对象的引用就+1,当一个对象的引用为0时,这个对象就可以被销毁掉;
  • 这个算法有一个很大的弊端就是会产生循环引用;

image.png

💡

标记清除:

  • 这个算法是设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于那些没有引用到的对象,就认为是不可用的对象;

image.png