← 返回目录

第 1 卷

第 1 / 19 卷日期:

JavaScript 核心知识点全面解答

  1. JavaScript代码是如何被执行的?

JavaScript代码的执行并非逐行直接执行,而是分两个核心阶段完成,且依赖JavaScript引擎与执行环境(浏览器/Node.js)的协作:

  1. 编译阶段(也叫创建阶段/预处理阶段):JavaScript引擎先对代码进行扫描和解析,完成执行上下

文创建、变量提升、函数提升、作用域确定等工作,为执行阶段做准备,该阶段不执行具体的代码逻辑。

  1. 执行阶段:在编译阶段的基础上,逐行执行代码,进行变量赋值、函数调用、表达式计算等操作,

同时会创建变量对象(VO/AO)、维护作用域链、处理this绑定等。

简单来说,JS代码执行遵循“先编译,后执行”的原则,先做好“准备工作”,再逐行执行具体逻辑。

  1. 什么是JavaScript引擎?常见的JavaScript引擎有哪些?
(1)JavaScript引擎定义

JavaScript引擎是专门用于解析和执行JavaScript代码的虚拟机(可理解为“JS代码的运行容器”),它负责将人类编写的JavaScript源代码转换为计算机能识别的机器码,从而实现代码的运

行,是浏览器或Node.js等环境的核心组成部分之一。

(2)常见JavaScript引擎
  1. V8引擎:由Google开发的开源高性能引擎,采用C++编写,不仅用于Chrome浏览器,也是

Node.js、Electron等环境的核心引擎。

  1. SpiderMonkey:历史最悠久的JS引擎,由Mozilla开发,用于Firefox浏览器。
  2. JavaScriptCore(JSC):由Apple开发,用于Safari浏览器、iOS系统及MacOS的部分应用。
  3. Chakra:由微软开发,早期用于Edge浏览器(后期Edge已切换为V8引擎),也用于Windows系

统的部分内置应用。

  1. V8引擎是如何执行JavaScript代码的?

V8引擎执行JS代码采用**“解释执行+编译执行”结合的混合模式**,核心分为以下几个步骤,兼顾启动速度和运行性能:

  1. 解析(Parse):首先将JavaScript源代码通过解析器(Parser)转换为抽象语法树(AST,
  1. 解释执行(Ignition 解释器):V8内置的解释器Ignition会将AST转换为字节码(Bytecode),并

直接解释执行字节码。这一步的优势是启动速度快,无需等待编译完成即可执行代码,适用于代码首次执行或短期执行的场景。

  1. 编译执行(TurboFan 编译器):在解释执行的过程中,V8的监控模块会统计代码的执行情况(如

是否为热点代码⸺频繁执行的代码)。当检测到某段代码是热点代码时,会将该段代码的字节码和相关执行信息传递给编译器TurboFan,TurboFan会将字节码编译为高度优化的机器码

(Machine Code)。

  1. 优化与反优化:机器码的执行效率远高于字节码,后续再执行该段热点代码时,会直接执行机器

码,提升运行性能。若后续代码的执行环境发生变化(如变量类型改变,破坏了TurboFan的优化假设),V8会进行反优化操作,将机器码还原为字节码,重新由Ignition解释执行。

  1. V8引擎的架构包括哪些部分,它们的作用是什么?

V8引擎的核心架构(主要组件)及各自作用如下:

  1. 解析器(Parser / Full Parser)

◦ 作用:负责将JavaScript源代码转换为抽象语法树(AST),同时进行语法校验。另外,V8还

包含一个预解析器(Preparser),用于对未立即执行的代码(如函数内部代码)进行浅解析,只校验语法合法性,不生成完整AST,提升代码启动速度。

  1. 解释器(Ignition)

◦ 作用:① 将AST转换为字节码;② 直接解释执行字节码,保证代码的快速启动;③ 收集代码执

行的统计信息(如执行次数、变量类型等),为TurboFan编译器提供优化依据。

  1. 编译器(TurboFan)

◦ 作用:接收Ignition传递的热点代码字节码和统计信息,将字节码编译为高度优化的机器码,提

升热点代码的执行效率;同时支持反优化操作,在优化假设失效时还原字节码。

  1. 垃圾回收器(Garbage Collector,GC)

◦ 作用:自动管理内存,负责识别和回收JavaScript代码中不再使用的内存空间(无用对象),

避免内存泄漏。V8的GC采用分代回收策略(新生代+老生代),兼顾回收效率和内存利用率。

  1. 内置函数库(Built-ins)

◦ 作用:提供JavaScript的内置对象(如Object、Array、String)和内置方法(如

Array.prototype.push、 JSON.parse)的实现,这些功能大多由C++编写,提供高效的底层支持。

  1. 执行上下文管理器

◦ 作用:管理执行上下文的创建、入栈、出栈,维护执行上下文栈(调用栈),负责变量提升、

5. 解释什么是变量提升?为什么JavaScript语言中存在变量提升这一机

制?

(1)变量提升(Hoisting)定义

变量提升是JavaScript在编译阶段的一种预处理行为:引擎在扫描代码时,会将所有使用 var 声明的变量和函数声明(Function Declaration)提升到其所在作用域的顶部,但变量的赋值操作不会被提

升,函数表达式也不会被完整提升。

示例:

Code block

1console.log(a); // undefined(变量a被提升,未赋值)

2var a = 10;

3 4fn(); // "执行函数"(函数声明被完整提升)

5function fn() { 6console.log("执行函数");

7} 8

9console.log(fn2);// undefined(函数表达式仅变量提升,函数体不提升)
10var fn2 = function() {
11console.log("函数表达式");
12};
(2)变量提升存在的原因
  1. 方便代码编写(历史设计):早期JavaScript设计的初衷是简化开发,允许开发者在变量或函数声

明之前使用它们,无需严格遵循“先声明后使用”的规则,提升开发效率。

  1. 支持函数相互调用:若不存在变量提升,函数之间无法相互调用(如函数A调用函数B,函数B又调

用函数A),变量提升使得函数声明可以被提前处理,支持这种相互依赖的场景。

  1. 与JS引擎执行机制匹配:JS引擎采用“先编译后执行”的模式,编译阶段需要确定变量和函数的存

在性,变量提升是该执行机制的自然产物,为执行阶段提供了变量和函数的访问依据。

  1. 变量提升机制有哪些潜在的缺点?它可能导致哪些具体问题?
(1)潜在缺点
  1. 破坏代码可读性和可维护性:变量可以在声明前使用,导致代码的执行逻辑与书写顺序不一致,开

发者阅读代码时难以快速追踪变量的声明和赋值位置。

全站分卷索引 · 19 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷