关于javascript:再学JS高级笔记1JS运行原理

42次阅读

共计 1975 个字符,预计需要花费 5 分钟才能阅读完成。

1 JavaScript 运行原理

1.1 浏览器的工作原理

JavaScript 代码在浏览器中是如何被执行的?

1.2 浏览器的内核

那么,向服务器申请了相干文件并下载了之后,是什么来解析咱们的 js 文件的呢?答案是 浏览器内核

实际上,咱们常常说的浏览器内核指的是浏览器的排版引擎:

  • 排版引擎 (layout engine) 也称为浏览器引擎 (browser engine)、页面渲染引擎(rendering engine) 或样板引擎
  • 不同的浏览器有不同的内核

    • Gecko
    • Trident
    • Webkit
    • Blink

1.3 浏览器渲染过程

如果在执行这个过程中,HTML 解析的时候遇到了 JavaScript 标签,应该怎么办呢?

  • 会进行解析 HTML,而去加载和执行 JavaScript 代码

那么 JavaScript 代码由谁来执行呢?

  • JavaScript 引擎

1.4 JavaScript 引擎

为什么须要 JavaScript 引擎?

  • 高级的编程语言都须要转成最终的机器指令来执行
  • 实际上咱们编写的 JavaScript 无论是交给浏览器或者 Node 执行最初是都须要被 CPU 执行的
  • CPU 只意识本人的指令集,只有机器语言能力被 CPU 所执行
  • 所以 须要 JavaScript 引擎帮忙咱们将 JavaScript 代码翻译成 CPU 指令能力被执行

常见的 JavaScript 引擎:

  • SpiderMonkey
  • Chakra
  • JavaScriptCode
  • V8:Google 开发的 JS 引擎,帮忙 Chrome 从泛滥浏览器中怀才不遇

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

以 WebKit 为例,WebKit 事实上由两局部组成:

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

小程序也是相似的,将代码分为两层:

  • Webview 渲染层:负责渲染 HTML 构造等
  • JsCore 逻辑层:负责解析执行 JavaScript 代码

1.6 V8 引擎

官网的定义:

  • V8 是用 C ++ 编写的 Google 开源高性能 JavaScript 和 WebAssembly 引擎,它用于 Chrome 和 Node.js 等
  • 能够在很多不同的操作系统上运行
  • V8 能够独立运行,也能够嵌入到任何 C ++ 应用程序中

V8 引擎自身的源码 非常复杂,大略有超过100w 行 C ++ 代码,通过理解它的架构,咱们能够晓得它是如何对 JavaScript 执行的:

  1. Parse模块:进行词法剖析和语法分析,将代码转换成 <u>AST(形象语法树)</u>,因为解析器并不间接意识 JS 代码
  • 如果函数没有被调用,那么是不会被转换成 AST 的
  • Parse 的 V8 官网文档:https://v8.dev/blog/scanner
  1. Ignition解释器:会将 AST 转换成ByteCode(字节码)
  • 同时会收集 TurboFan 优化所须要的信息(比方函数参数的类型信息,有了类型能力进行实在的运算)
  • 如果函数只调用一次,Ignition 会执行解释去执行 ByteCode
  • pIgnition 的 V8 官网文档:https://v8.dev/blog/ignition-interpreter
  • 字节码是能够 跨平台 的,所以当运行的时候 cpu 会将字节码转成相干平台的汇编代码,再转换成 cpu 指令
  1. TurboFan编译器:能够将字节码编译为 CPU 能够间接执行的机器码
  • 如果一个函数被屡次调用,会被标记为 热点函数,那么就会通过 TurboFan 转换成优化的机器码,进步代码的执行性能
  • 然而机器码实际上也会被还原为 ByteCode。这是因为如果后续执行函数的过程中,类型产生了变动(比方 sum 函数原来执行的是 number 类型,起初执行变成了 string 类型),之前优化的机器码并不能正确地解决运算,就会 逆向 地转换成字节码(Deoptimization)
  • TurboFan 的 V8 官网文档:https://v8.dev/blog/turbofan-jit

1.7 V8 执行过程的细节

JavaScript 源码是如何被解析 (parse 过程) 的呢?

  1. Blink(内核)将 JS 代码交给 V8 引擎,Stream获取到 JS 代码并且进行编码转换
  2. Scanner(扫描器)会进行词法剖析(lexical analysis),词法剖析会将代码转换成 tokens
  3. 接下来 tokens 会通过 ParserPreparser,被转换成 AST 树
  • Parser就是间接将 tokens 转成 AST 树架构
  • PreParser称为预解析,为什么须要预解析呢?

    • 因为不是所有的 JavaScript 代码在一开始时就会被执行,那么对所有代码进行解析必然会影响网页的运行效率
    • 所以 V8 引擎就实现了 Lazy Parsing(提早解析)的计划,它的作业是将不必要的函数进行预解析,也就是只解析临时须要的内容。而对函数的全量解析是在函数被调用时才会进行
  • 生成的 AST 树只会被 Ignition 转成字节码
  • 之后的过程就是代码的执行过程
正文完
 0