深入理解 V8 引擎与 JavaScript 执行机制
一、 V8 引擎概述
V8 是 Google 开发的高性能 JavaScript 引擎,用于 Chrome 和 Edge 浏览器以及 Node.js。它的核心功能是将 JavaScript 代码转换为机器码并执行。
二、V8 执行JS代码的过程
分词/词法分析(Parsing):将代码分成词法单元。
js
const x = 10 + 20
代码片段 | Token 类型 |
---|---|
const | Keyword |
x | Identifier |
= | Assignment |
10 | Number |
+ | Operator |
20 | Number |
解析和语法分析:根据语法规则生成抽象语法树(AST),检查代码是否符合语法规则。
- 检查
const
→ 变量声明 - 检查
x
→ 变量名 - 检查
=
→ 赋值 - 检查
10 + 20
→ 二元运算表达式
代码生成: 将 AST 转换为可执行的机器码(或字节码)。
三、 作用域
作用: 存放变量的值并能在之后对这个值进行访问和修改。
- 全局作用域:在代码最外层声明的变量或函数,可以在任何地方访问。
js
count a = 1 //全局作用域
function showGlobal(){
console.log(a); //可以访问
}
showGlobal(a) // 1
console.log(a); //1
注意:全局变量容易被污染,导致命名冲突。
- 函数作用域:在函数内部声明的变量,只能在该函数及其嵌套函数内访问。
js
function outer() {
var funcVar = "I'm in outer"; // 函数作用域变量
function inner() {
console.log(funcVar); // 可以访问(闭包)
}
inner(); // "I'm in outer"
}
outer();
console.log(funcVar); // ReferenceError: funcVar is not defined
- 块级作用域:由
{}
(如if
、for
、while
) +let/const
形成的作用域。
js
if (true) {
let blockVar = "I'm in block"; // 块级作用域变量
const PI = 3.14; // 块级作用域常量
console.log(blockVar); // "I'm in block"
}
console.log(blockVar); // ReferenceError: blockVar is not defined
console.log(PI); // ReferenceError: PI is not defined
let
和const
+{}
是块级作用域。var
没有块级作用域,它会提升到最近的函数或全局作用域:
总结
- 全局作用域:
- 最外层,随处可访问。
- 容易污染全局命名空间,慎用。
- 函数作用域:
var
和function
声明的作用域。- 支持闭包,内部函数可访问外部变量。
- 块级作用域:
let
和const
的作用域。- 避免变量提升问题,更安全。
最佳实践 :
✔ 优先使用 let
/const
(避免 var
的变量提升和泄漏)
✔ 避免滥用全局变量(防止命名冲突)
✔ 合理使用闭包(避免内存泄漏)
四、作用域链
V8 引擎查找变量时,会沿着作用域链向上查找:
- 先在当前作用域查找。
- 如果找不到,向上一级作用域查找。
- 直到全局作用域,如果仍未找到,报
ReferenceError
。
js
let global = "global";
function outer() {
let outerVar = "outer";
function inner() {
let innerVar = "inner";
console.log(innerVar); // "inner"(当前作用域)
console.log(outerVar); // "outer"(上层作用域)
console.log(global); // "global"(全局作用域)
}
inner();
}
outer();
五、附加let、const、var区别
- let、const 声明的变量不存在声明提升。
- let、const 声明的变量不能重复声明。
- var 声明的全局变量会被挂载到 window上。
- const 声明的变量 值不能改。