信息发布→ 登录 注册 退出

javascript变量提升是什么_let和const如何改变了这种现象?

发布时间:2026-01-11

点击量:
变量提升只提升var声明(不包括赋值),let/const虽声明提升但受TDZ限制,访问会报错;var函数作用域且可重复声明,let/const块级作用域且不可重复声明。

变量提升(Hoisting)到底提升了什么?

JavaScript 中的“变量提升”不是把变量声明和赋值一起挪到顶部,而是只把 var 声明部分(不包括初始化)移到当前作用域顶部,赋值仍保留在原位置。这意味着你能在声明前访问 var 变量,但值是 undefined,而不是报错。

常见错误现象:

  • 以为 console.log(a) 会报 ReferenceError,结果输出 undefined
  • 在函数内用 var 声明同名变量,意外覆盖了外层变量却没察觉
console.log(a); // undefined
var a = 123;

letconst 为什么不再“提升”?

它们确实也经历了声明提升,但被放入了「暂时性死区」(Temporal Dead Zone, TDZ)。也就是说:声明被提升,但直到实际执行到那行代码前,都不能读写该变量——任何访问都会抛出 ReferenceError

关键区别在于:TDZ 强制你必须「先声明、后使用」,而 var 允许「先用、后声明」(只是值为 undefined)。

使用场景提醒:

  • 函数参数默认值中引let/const 声明的变量,会立即触发 TDZ 错误
  • for 循环中用 let 声明计数器,每次迭代都有独立绑定,避免闭包陷阱
  • const 声明的对象属性仍可修改,它只限制「重新赋值」,不冻结内容
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 456;

varletconst 的作用域与重复声明规则

三者的作用域行为差异比提升更直接影响代码逻辑:

  • var 是函数作用域(或全局),允许重复声明;在块(如 iffor)中声明会被提升到函数顶部
  • letconst 是块级作用域,不允许重复声明(同一作用域下),且 const 必须初始化
  • var 在全局作用域下会成为 window 属性(浏览器环境),let/const 不会
if (true) {
  var x = 1;
  let y = 2;
}
console.log(x); // 1 —— var 被提升到函数/全局作用域
console.log(y); // ReferenceError —— y 只存在于 if 块内

容易被忽略的细节:函数声明 vs 函数表达式

函数声明(function foo() {})会被完全提升(声明 + 定义),而函数表达式(const foo = function() {})按 const 规则处理,受 TDZ 约束。

这也意味着:

  • var 写函数表达式(var foo = function() {})只会提升 var foofoo 值仍是 undefined,直到执行到赋值行
  • 箭头函数始终是表达式,无论用 let 还是 const 声明,都遵循 TDZ
  • 类声明(class Foo {})也受 TDZ 约束,不能在声明前使用

真正要警惕的,不是“有没有提升”,而是“提升后能不能安全访问”。letconst 把隐式错误变成了显式报错,但前提是你要意识到自己正处在块内、参数默认值里,或者 eval 上下文中——这些地方 TDZ 的边界并不总是直观。

标签:# javascript  # java  # 浏览器  # access  # win  # 区别  # 作用域  # 为什么  
在线客服
服务热线

服务热线

4008888355

微信咨询
二维码
返回顶部
×二维码

截屏,微信识别二维码

打开微信

微信号已复制,请打开微信添加咨询详情!