es6 中 let 和 const 声明的全局变量不属于顶层对象(如 window)属性,仅存在于全局词法环境中;var/function 声明的仍挂载到 window 以保持兼容,此举旨在避免命名冲突、防止污染全局空间并支持模块化。

因为 ES6 明确规定:let 和 const 声明的全局变量不属于顶层对象(浏览器中是 window)的属性,这是语言标准的设计变更,不是 bug 或兼容问题。
顶层对象与全局变量的“脱钩”
ES5 中,var 和 function 声明的全局变量会自动成为顶层对象(window)的属性,本质是“全局变量 ≡ window 属性”。ES6 为增强模块化和安全性,将两者分离:
- var/function 声明的全局变量 → 仍挂载到 window 上(保持向后兼容)
- let/const/class/import 声明的全局变量 → 只存在于全局词法环境(Script 级块级作用域)中,不作为 window 的属性存在
执行环境与变量存储方式不同
var 变量在创建执行环境时就被加入变量对象(VO),而 window 是全局 VO 的代理;let/const 则是在执行阶段才被绑定到当前词法环境的词法环境记录(Lexical Environment Record)中,这个记录独立于 window 对象,也不暴露给外部访问。
用于 inference.sh 的 JavaScript/TypeScript SDK,可运行 AI 应用、构建代理、集成 150+ 模型。包名:@inferencesh/sdk(npm install),完整 TypeScript 支持。
你可以理解为:它们被存放在一个“看不见但可直接使用”的全局块级作用域里,而不是挂在 window 这个公开属性表上。
实际表现与验证方式
运行以下代码就能清晰看到区别:
var a = 1; let b = 2; const c = 3; console.log(window.a); // 1 console.log(window.b); // undefined console.log(window.c); // undefined console.log(b, c); // 2, 3 —— 直接访问完全正常,只是不通过 window
这说明变量本身存在且可访问,只是访问路径不再是 window.xxx,而是直接按词法作用域查找。
设计目的很明确
- 避免污染全局命名空间(比如库之间用 let 声明同名变量互不影响)
- 防止意外覆盖 window 原有属性(如 window.name、window.location 等)
- 支持更严格的模块隔离和静态分析(如 tree-shaking)
- 为未来标准(如 import/export)提供干净的全局语义基础










