JavaScript 引擎概述
JavaScript 引擎是一个专门执行 JavaScript 代码的程序或解释器,负责将人类可读的 JavaScript 代码转换为机器可执行的指令,其中主流的javascript引擎有主流的 JavaScript 引擎包括 Google 的 V8(用于 Chrome 和 Node.js)、苹果的 JavaScriptCore(用于 Safari 和 iOS)和 Mozilla 的 SpiderMonkey(用于 Firefox)。此外,微软曾开发过 Chakra 用于 Internet Explorer。
JavaScript 引擎工作流程
执行过程
引擎处理流程:
源代码 → 解析 → 编译 → 执行 → 优化
JavaScript 引擎的工作流程是一个复杂的多阶段过程:
1. 解析阶段: 源代码 → Tokens → AST
2. 编译阶段:
- 解释器: AST → 字节码
- 基线编译器: 快速生成机器码
- 优化编译器: 对热点代码深度优化
3. 执行阶段: 执行字节码/机器码
4. 优化阶段: 内联缓存、函数内联、逃逸分析等
5. 内存管理: 分代垃圾回收,自动内存管理
JavaScript 作用域(scop)机制
作用域基本概念:作用域是变量和函数的可访问范围,决定了代码中标识符的可见性
作用域类型
-
全局作用域:在任何函数外部声明的变量属于全局作用域,这些变量可以在代码的任何地方被访问。在浏览器环境中,全局变量会成为 window 对象的属性;在 Node.js 中,则属于 global 对象
-
函数作用域:在函数内部声明的变量属于函数作用域,只能在该函数内部访问,外部无法直接访问。函数参数也属于函数作用域
-
块级作用域:ES6 引入 let 和 const 后新增的作用域类型,由 {} 代码块(如 if 语句、for 循环等)形成。let 和 const 声明的变量只在当前代码块内有效,var 声明的变量不受块级作用域限制
-
词法作用域(静态作用域) :JavaScript 默认的作用域机制,作用域由代码的书写位置决定,在函数定义时就已确定,与执行位置无关。内部函数可以访问外部函数的作用域链上的变量
-
模块作用域:ES6 模块中运行代码的作用域,模块内的变量和函数需要明确导出才能被其他模块访问,有助于组织代码和避免命名冲突
var 的变量提升
js的执行
代码被v8读取到的第一时间,并不是执行,而是会先编译(梳理)
- 梳理:
- 分词/词法分析
- 解析/语法分析 -- AST
- 生成代码
let 和 const 的暂时性死区 (Temporal Dead Zone)
总结
JavaScript 引擎和作用域机制是理解 JavaScript 运行原理的核心:
- 引擎负责执行代码,通过解析、解释、编译和优化等步骤
- 作用域决定可见性,包括全局、函数和块级作用域
- 作用域链实现变量查找,基于词法作用域
- 闭包保持对外部变量的引用,实现数据封装
- 执行上下文管理代码执行环境