var声明的变量会挂载到window对象上,let和const则不会;var存在变量提升且无暂时性死区,let和const存在暂时性死区且不提升;let和const具有块级作用域,const声明后不可重新赋值。

在顶级作用域(即全局作用域,非函数、非模块内部)中声明变量时,var、let 和 const 的行为有本质区别,其中最直观的差异之一就是它们是否被挂载到浏览器环境的 window 对象上。
var 声明的变量会自动挂载到 window
使用 var 在顶级作用域声明变量,该变量会成为 window 的属性,可直接通过 window.变量名 访问:
-
var a = 42;→window.a === 42为 true - 即使未赋值,
var b;也会挂载,window.b为undefined - 这是历史行为,源于早期 JavaScript 将全局
var视为“全局对象的属性”
let 和 const 声明的变量不会挂载到 window
let 和 const 在顶级作用域声明的变量属于“全局词法环境”,但不绑定到 window:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
let x = 100;→window.x是undefined(不是ReferenceError,因为window.x可读,只是没这个属性) -
const y = 'ok';→window.y同样为undefined - 它们存在于全局作用域,可直接访问
x或y,但不可通过window代理访问
为什么设计成这样?
这种差异不是偶然,而是语言演进的关键改进:
立即学习“Java免费学习笔记(深入)”;
-
var的挂载行为容易引发命名污染和意外覆盖(比如库脚本与用户代码冲突) -
let/const引入块级作用域的同时,也解耦了“全局变量”与“全局对象属性”的强绑定 - ES6 明确规定:仅
var和function声明会创建全局对象属性;let、const、class、import等均不参与挂载
注意边界情况
以下情形不改变上述规则:
- 在严格模式下,
var依然挂载,let/const依然不挂载 - 模块(
.mjs或type="module")中,顶级作用域本身不是全局作用域,var也不会挂载到window - 直接给
window赋值(如window.z = 99)始终有效,但这与声明方式无关

















