let const var 底层区域别,es6还有AO 对象和GO对象吗
在 JavaScript 中,var
、let
、const
的底层行为差异与 作用域规则 和 变量存储机制 密切相关。ES6 引入了 块级作用域 和 词法环境(Lexical Environment),改变了原有的 AO
和 GO
的实现方式,但核心逻辑仍然保留。以下是详细解释:
一、var
、let
、const` 的底层区别
特性 | var | let | const |
---|---|---|---|
作用域 | 函数作用域或全局作用域 | 块级作用域 | 块级作用域 |
变量提升 | 提升并初始化为 undefined | 提升但未初始化(TDZ) | 提升但未初始化(TDZ) |
重复声明 | 允许 | 不允许 | 不允许 |
暂时性死区(TDZ) | 无 | 有 | 有 |
全局对象绑定 | 是(绑定到 window ) | 否(存储在词法环境) | 否(存储在词法环境) |
可重新赋值 | 是 | 是 | 否(常量不可变,对象属性可变) |
1. 作用域
var
:作用域为函数或全局,没有块级作用域。if (true) { var a = 10; // 变量 a 泄露到全局 } console.log(a); // 10
let
/const
:作用域为块级({}
内部)。if (true) { let b = 20; const c = 30; } console.log(b); // ReferenceError console.log(c); // ReferenceError
2. 变量提升与 TDZ
var
:变量提升并初始化为undefined
。console.log(a); // undefined var a = 10;
let
/const
:变量提升但未初始化,访问会触发 暂时性死区(TDZ)。console.log(b); // ReferenceError: Cannot access 'b' before initialization let b = 20;
3. 全局对象绑定
var
:全局声明的变量会绑定到window
(浏览器)或global
(Node.js)。var globalVar = 10; console.log(window.globalVar); // 10
let
/const
:全局声明的变量存储在 全局词法环境,不绑定到window
。let globalLet = 20; console.log(window.globalLet); // undefined
二、ES6 中的 AO 和 GO:词法环境与变量环境
ES6 引入了 词法环境(Lexical Environment) 和 变量环境(Variable Environment),取代了 ES5 的 AO
和 GO
的底层实现,但核心逻辑类似。
1. 执行上下文的组成
每个执行上下文(全局/函数/块)包含:
- 词法环境(Lexical Environment):存储
let
/const
声明的变量。 - 变量环境(Variable Environment):存储
var
声明的变量(类似旧的 AO/GO)。 - 外部环境引用(Outer Reference):形成作用域链。
2. 全局环境
- 全局词法环境:存储
let
/const
声明的全局变量。 - 全局变量环境:存储
var
声明的全局变量,并绑定到window
(浏览器)。 - 全局对象(GO):如
window
,但let
/const
不与它绑定。
3. 函数/块级环境
- 函数执行时:
- 创建新的词法环境(存储
let
/const
)。 - 创建变量环境(存储
var
,类似旧的 AO)。
- 创建新的词法环境(存储
- 块级作用域(如
if
/for
):- 创建新的词法环境,存储块内的
let
/const
。
- 创建新的词法环境,存储块内的
三、ES6 后的 AO 和 GO 是否还存在?
- 逻辑上存在,实现方式变化:
- AO(活动对象):被拆分为 词法环境 和 变量环境,
var
声明存储在变量环境中(类似旧的 AO),let
/const
存储在词法环境中。 - GO(全局对象):
window
或global
依然存在,但let
/const
的全局变量不绑定到它,而是存储在全局词法环境。
- AO(活动对象):被拆分为 词法环境 和 变量环境,
代码示例
var a = 10;
let b = 20;
const c = 30;
// 全局变量环境(存储 var)
console.log(window.a); // 10
// 全局词法环境(存储 let/const)
console.log(window.b); // undefined
console.log(window.c); // undefined
四、关键总结
var
的底层行为:- 存储在变量环境(类似 AO/GO),存在变量提升,无块级作用域。
let
/const
的底层行为:- 存储在词法环境,有块级作用域和 TDZ。
- ES6 的环境模型:
- 词法环境和变量环境共同管理作用域,取代了单一的 AO/GO。
- 全局对象(GO):
- 仍然存在,但仅
var
会绑定到它,let
/const
通过词法环境隔离。
- 仍然存在,但仅
五、扩展:词法环境的结构
词法环境是一个 环境记录(Environment Record) 的链表结构,包含:
- 声明式环境记录:存储变量和函数声明。
- 对象式环境记录:如
with
语句创建的绑定到对象的记录。
// 示例:作用域链的嵌套结构
function outer() {
var x = 10;
let y = 20;
function inner() {
console.log(x + y); // 访问外层变量
}
inner();
}
outer();
inner
的词法环境链:inner 词法环境 → outer 词法环境 → 全局词法环境
。
理解这些底层机制,可以更好地掌握闭包、作用域链、变量提升等核心概念,避免常见的陷阱(如循环中的 var
泄露)。