贝利信息

javascript中的变量声明有哪些方式?_let、const和var有什么区别?【教程】

日期:2026-01-21 00:00 / 作者:夢幻星辰
var变量提升但赋值不提升,let/const有暂时性死区且块级作用域;循环中var共享绑定而let每次迭代新建绑定;默认用const,需重赋值才用let。

var 声明的变量会“提升”,但赋值不会

声明会被移到作用域顶部,但初始化(即等号右边的值)仍保留在原位置。这意味着 var a = 1 实际上被拆成两步:var a 提升,a = 1 留在原地。

常见错误现象:console.log(a) 输出 undefined 而非报错,即使它写在声明之前。

let 和 const 是块级作用域,但行为不同

letconst 都绑定到最近的块({}),且不存在变量提升——它们有“暂时性死区”(TDZ):从块开始到声明语句执行前,访问会直接抛出 ReferenceError

关键区别在于可变性:

var / let / const 在循环中的表现差异明显

这是最容易踩坑的场景之一。用 var 声明的循环变量,在异步回调中往往拿到的是最后一次迭代的值。

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0) // 输出 3、3、3
}

let 每次迭代都会创建一个新的绑定:

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0) // 输出 0、1、2
}

默认应该用 const,需要重赋值才用 let

这不是教条,而是基于实际维护成本的判断:越少可变状态,越不容易出错。90% 以上的变量其实不需要重赋值。

例如函数参数、DOM 查询结果、API 返回数据、配置对象——这些通常只需一次赋值,就该用 const

真正容易被忽略的是:块级作用域不只存在于 iffor,还出现在 try/

catch
catch 绑定、模块顶层、甚至 IIFE 外部——constlet 的作用域边界比直觉中更细、更严格。