📜  Node.js 和 V8 有什么关系?

📅  最后修改于: 2022-05-13 01:56:35.131000             🧑  作者: Mango

Node.js 和 V8 有什么关系?

Node.js 是一个开源、跨平台的后端 JavaScript 运行环境,构建在 V8 引擎之上,在浏览器之外执行 Javascript 代码。 Javascript 运行时环境包含执行 JS 代码所需的所有组件。 JavaScript 最初设计为仅在浏览器中运行。所有浏览器都配备了用于运行 JavaScript 的 JavaScript 引擎。例如,Mozilla Firefox 由 Spidermonkey 提供支持,而 Chrome 使用 V8 引擎。 JavaScript 引擎不是机器,而是执行 JavaScript 代码并使计算机能够在硬件级别执行特定任务的程序或解释器。当 Ryan Dahl 意识到 V8 引擎在 Chrome 浏览器中的潜力并将其扩展为作为独立应用程序运行时,他创建了 Node.js。计算机只能解释机器码,而 Javascript 是一种高级语言,所以我们需要一个编译器来将 Javascript 翻译成机器码。 Node.js 只是一个支持程序执行的运行时环境。 V8 是 Node.js 的核心。

没有 V8,Node.js 无法运行。由于没有 JavaScript 引擎,所以没有 JS 可以在这样的环境中运行。 Chrome V8 引擎采用人类可读的 Javascript 代码并将其转换为更优化的机器代码。它是一个用 C++ 编写的开源多线程程序。该引擎最初是为 Web 浏览器执行而设计的,但最新版本还在浏览器之外执行 JS 代码,从而启用服务器端脚本。它独立于执行它的浏览器。这一特性激发了设计人员选择 V8 引擎来支持 Node.js。 Node.js 是用 C++ 编写的。 V8 引擎嵌入在 node.js 代码中,为代码添加了额外的功能。因此,C++ 代码的理解程度超过了 ECMAScript 标准的其他规定。 V8 引擎和 node.js 是可互操作的。它们共同构成了开发应用程序的强大组合。 V8 引擎是 Node.js 的核心。

V8引擎的工作: Js引擎是早期的解释器,逐行执行代码,不需要编译,使得过程非常慢,因为在执行之前分析每个语句以执行所需的任务。随着 V8 的出现,它通过使用单独的线程来加速编译过程来解决这个问题。 V8 采用了Just in Time (JIT)编译器的技术。即时编译器结合了解释器和编译器的最佳特性,使翻译和执行速度更快。解释器逐行执行代码,编译后的代码在运行时动态地进行额外优化(和重新优化)。现在,问题是 Javascript 是解释型语言还是编译型语言。 Javascript 可以是解释型语言也可以是编译型语言,具体取决于 JS 引擎。

V8 使用以下线程。

1. 主线程: FETCH 线程执行获取代码并确保其正在编译和执行的主要任务。

2. 编译线程:以前的V8版本使用两个线程进行编译。

  • Full-codegen:这会将 JS 编译成简单且相对较慢的机器代码。使用 full-codegen,解析后的 JavaScript 无需任何转换即可直接转换为机器代码。因此,执行机器代码非常快。
  • Crankshaft:它编译多次运行的代码段,通常称为热段,最好在下次遇到这部分代码时更有效地执行它们。

该线程进行了某些优化。

  • 内联:将函数的调用替换为函数的代码,从而提高性能。
  • 隐藏类: JavaScript 是一种动态语言,因此可以轻松添加或删除属性。因此,跟踪每个属性变得昂贵,它使用隐藏类的方法。添加新属性时,将向每个对象的旧隐藏类添加新隐藏类的转换路径。
  • 内联缓存: V8 维护在最近的方法调用中作为参数传递的对象类型的缓存,并使用该数据来猜测未来将传递什么类型的对象。

3. Profiler Threads :通知运行时哪些方法占用了我们大部分时间,因此 Crankshaft 可以优化它们

4.垃圾线程:使用标记和清除算法释放内存管理空间。

让我们看看 V8 引擎如何执行 Node.js 内部编写的 JS 代码

在 node.js 中执行 Javascript

1.解析:将Javascript源代码解析并转换为抽象语法树(AST)。代码被分解为令牌。令牌是我们代码的构建块,是构成代码的任何东西。例如,让 a = 5。这里的 let, a, =, 5 是记号。

let a = 5 

Ast 在程序的语义分析中起着至关重要的作用,因为编译器会验证应用程序和语言元素的正确性和正确使用。

让我们通过以下示例查看 AST 的表示:

const blog = "GeeksforGeeks"

AST 表示

JSON 中的 AST 表示

{
  "type": "Program",
  "start": 0,
  "end": 28,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 28,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 6,
          "end": 28,
          "id": {
            "type": "Identifier",
            "start": 6,
            "end": 10,
            "name": "blog"
          },
          "init": {
            "type": "Literal",
            "start": 13,
            "end": 28,
            "value": "GeeksforGeeks",
            "raw": "\"GeeksforGeeks\""
          }
        }
      ],
      "kind": "const"
    }
  ],
  "sourceType": "module"
}

2. 编译:Ignition 从语法树中生成一个称为字节码的中间代码。

3. 执行:Turbofan 将此字节码转换为高度优化的机器码。机器代码在系统上运行。

至此,我们了解了 Node.js 和 V8 引擎的关系,得出结论,没有 V8 这样的 JavaScript 引擎是无法运行 Node.js 的。