JavaScript 引擎的理解
一、什么是 JavaScript 引擎
JavaScript 引擎是一个专门处理 JavaScript 代码的程序。它负责解析和执行 JavaScript 代码,将我们编写的 JavaScript 代码转换为机器能够理解和执行的机器码。
目前主流的 JavaScript 引擎有:
- V8(Google):用于 Chrome 浏览器和 Node.js
- SpiderMonkey(Mozilla):用于 Firefox 浏览器
- JavaScriptCore(Apple):用于 Safari 浏览器
- Chakra(Microsoft):用于 IE 和 Edge 浏览器(旧版)
二、主要组成部分
1. Memory Heap(内存堆)
- 用于存储对象、数组等引用类型数据
- 进行动态内存分配
- 包含垃圾回收机制(分代回收、标记清除、引用计数等)
- 处理内存碎片化问题
2. Call Stack(调用栈)
- 记录代码执行的上下文
- 基于 LIFO(后进先出)原则
- 包含以下信息:
- 局部变量
- 参数
- 返回地址
- 临时变量
3. Parser(解析器)
解析过程分为两个阶段:
词法分析(Tokenization)
1
2
3
4
5
6
7
8
9// 源代码:let name = "John";
// 被解析为 tokens:
[
{ type: "keyword", value: "let" },
{ type: "identifier", value: "name" },
{ type: "operator", value: "=" },
{ type: "string", value: "John" },
{ type: "punctuator", value: ";" }
]语法分析(生成 AST)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// AST 结构示例
{
type: "Program",
body: [{
type: "VariableDeclaration",
declarations: [{
type: "VariableDeclarator",
id: {
type: "Identifier",
name: "name"
},
init: {
type: "Literal",
value: "John"
}
}]
}]
}
4. Interpreter(解释器)
- 直接执行字节码
- 维护执行上下文
- 处理作用域链
- 实现变量提升
- 管理闭包
5. Compiler(编译器)
包含多个优化阶段:
JIT(即时编译)
1
2
3
4
5
6
7
8
9// 热点函数会被编译优化
function hotFunction(n) {
// 被多次调用的函数
return n * 2;
}
for(let i = 0; i < 100000; i++) {
hotFunction(i); // 这个函数会被 JIT 编译
}内联缓存(Inline Caching)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 优化前
function getName(obj) {
return obj.name;
}
// V8 优化后的伪代码
function getName(obj) {
// 检查对象结构是否匹配缓存
if (obj.map === cachedMap) {
// 直接返回固定偏移量的属性
return *(obj + nameOffset);
}
// 回退到常规属性访问
return obj.name;
}
三、工作流程
1. 加载阶段
- 源码加载
- 词法分析
- 语法分析
- 生成 AST
- 生成字节码
2. 执行阶段
创建执行上下文
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17ExecutionContext = {
ThisBinding: <this value>,
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 标识符绑定
},
outer: <outer lexical environment reference>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 变量和函数声明
},
outer: <outer lexical environment reference>
}
}作用域链建立
1
2
3
4
5
6
7
8
9function outer() {
const a = 1;
function inner() {
const b = 2;
console.log(a, b);
}
return inner;
}
// 作用域链:inner -> outer -> global变量对象创建
代码执行
3. 优化阶段
死代码消除
1
2
3
4
5
6
7
8
9
10
11
12// 优化前
function unused() {
const a = 1;
const b = 2;
return a; // b 永远不会被使用
}
// 优化后
function unused() {
const a = 1;
return a;
}内联展开
1
2
3
4
5
6
7
8// 优化前
function add(a, b) {
return a + b;
}
let result = add(1, 2);
// 优化后
let result = 1 + 2;
四、性能优化
1. 代码层面
1 | // 1. 对象属性访问优化 |
2. 内存管理
1 | // 1. WeakMap 使用 |
五、注意事项
1. 内存泄漏
1 | // 1. 闭包导致的内存泄漏 |
2. 执行效率
1 | // 1. 避免动态属性访问 |
六、高级优化技巧
1. Hidden Class
1 | // 不推荐 |
2. 函数优化
1 | // 1. 单态函数 |
参考文献
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 BlogMind!