JavaScript 里 var、let 与 const 有什么区别?新手怎么一次选对

编程狮(w3cschool.cn) 2026-08-11 15:09:09 浏览数 (18)
反馈

一句话结论先给你:在 JavaScript 里声明变量,默认用 const,需要重新赋值就用 let,var 基本可以不再写。var、let、const 这三个关键字都能声明变量,看起来差不多,其实在作用域、变量提升、能不能重复声明上完全不是一回事,用错就容易出现那些"时灵时不灵"的 bug。你照着老教程写 JS,满屏都是 var;看新视频,老师又让你用 let 和 const,彻底懵了也很正常。之所以要搞清楚 var let const 区别,是因为它们决定了变量在哪能用、什么时候有值、能不能被改,这几个差异直接关系到代码会不会出怪问题。本文基于现代浏览器和 ES6 标准,用大白话把三者的关键区别讲清楚,并给出实战里怎么选的建议。今天这篇文章,编程狮就把它一次性讲透。

一、先记住一句话结论:优先 const,其次 let,var 靠边

团队里约定俗成的写法是:声明一个值以后不会变的,用 const;后面需要重新赋值的,用 let;至于 var,新项目基本可以不再写。这个结论不是拍脑袋定的,背后是三者作用域和提升行为的差异。var 是 ES5 时代就有的老语法,当时还没有块级作用域的概念,自然会带出一堆坑;let 和 const 是 ES6 引入的,专门用来修补 var 的那些问题。理解了这段来龙去脉,后面讲具体区别时就很好懂了。也正因为如此,现在主流的代码规范和教学都建议:能写 const 就别写 let,能写 let 就别写 var。把这条记牢,你后面写代码会少踩很多坑,尤其是在和别人协作、读别人代码的时候,风格统一也很重要。说到底,把 var let const 区别 吃透,比背任何一句口诀都管用,因为它决定了你写出来的代码到底稳不稳。

二、区别一:作用域不同(var 函数级,let/const 块级)

作用域,说得通俗点就是"变量在哪些范围内能被访问到"。要弄懂 var let const 区别,先从作用域看起。var 是函数级作用域:它在整个函数里都有效,哪怕写在 if、for 这样的代码块里,出了块在外面也照样能读到。let 和 const 则是块级作用域:只在当前一对大括号 {} 里有效,出了这个块就访问不到了。这个差异看起来很小,却是 var 最容易出 bug 的地方,很多"我明明改了值怎么没生效"的困惑都源于此。

最经典的坑是这样的:用 var 声明循环变量 i,在定时器里打印它,结果和你预期完全不同。要分清 var let const 区别,这个例子是最直观的入口,建议你亲手敲一遍,体会块级作用域带来的差别。

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// 输出 3 3 3,而不是 0 1 2

为什么会这样?因为 var 让 i 漏到了循环外面,三个定时器读的是同一个最终值 3。把 var 换成 let,每次循环都有自己的 i,就能正确输出 0 1 2。这个例子很能说明问题:块级作用域能避免很多"变量被意外改掉"的 bug,这也是 let、const 更受推荐的核心原因。想随时查语法细节,JavaScript 速查手册 可以贴在手边,遇到记不清的写法随时翻。

三、区别二:变量提升与暂时性死区

var 有"变量提升":不管你写在哪个位置,声明都会被提到函数的顶部,只是赋值留在原地。所以你提前读取一个 var 变量,得到的是 undefined 而不会报错,因为声明已经"升"上去了,只是值还没赋。let 和 const 也会被提升,但和 var 不同,它们在声明之前访问会直接报错,这段"声明前不能用"的区间就叫暂时性死区。

console.log(x); // undefined(var 提升,值还没赋)
var x = 10;


console.log(y); // 报错:暂时性死区
let y = 20;

暂时性死区其实是一件好事:它逼你在用变量之前先声明,代码逻辑更清晰,也更不容易出现那种"怎么读出来是 undefined"的怪问题。相关概念拿不准,在线编程词典 里能查到更细的解释。简单记一句话:var 是"提前能用,但值是 undefined",let/const 是"提前用就直接报错"。对新手来说,后者的行为更直观、更安全,不容易被提升机制悄悄坑到,调试时也更省心。很多新手都栽在提升机制上,所以 var let const 区别 里这一条尤其值得单独记住,调试时一眼就能定位问题。

四、区别三:能否重复声明、const 能不能改

var 允许在同一个作用域里重复声明同一个变量,后面的覆盖前面的,这很容易埋坑——你可能不小心写了两次同名变量而不自知,运行起来逻辑就乱了。let 和 const 不允许重复声明,写了会直接报错,反而更安全,能帮你及早发现笔误。

关于 const 有个非常常见的误解,必须单独讲清楚:它限制的是"不能重新赋值",不是"值不能改"。用 const 声明的叫常量,意思是这个变量名不能重新指向别的数据;但如果它存的是对象或者数组,你照样能修改里面的属性或元素,只是不能让变量名指向另一个对象。

const arr = [1, 2];
arr.push(3);   // 允许,改的是内容
arr = [9];     // 报错,不能重新赋值

下面把三者摆在一起对比,方便你一眼看清差异:

维度 var let const
作用域 函数级 块级 块级
变量提升 有,值为 undefined 有,但暂时性死区 有,但暂时性死区
重复声明 允许 不允许 不允许
重新赋值 允许 允许 不允许

看完这张表你应该能确认:var 几乎在每一项上都不如 let/const 稳妥,这也是为什么新项目普遍建议放弃 var。当你拿不准用哪个时,先写 const,如果编译器提示"需要重新赋值"再改成 let,这个顺序最不容易出错。

总结

var let const 区别的核心就三点:作用域上 var 是函数级、let/const 是块级;提升行为上 var 提前读是 undefined、let/const 会进暂时性死区;重复声明上只有 var 允许。记住实战口诀:默认用 const(值不变最安全,声明的常量不能重指);需要重新赋值再用 let;新项目基本告别 var。把这三句话刻进肌肉记忆,你写出来的代码会稳得多,也更容易和团队规范对齐。想系统把前端基础打牢,可以顺着下面的路径继续走。

延伸学习

想理清前端基础,可以按这个顺序来:

  1. 想规划学习路线,前端开发学习路线 帮你从基础到进阶;
  2. 想边学边练,前端实战入门课程 是边看边写的形式;
  3. 想动手做项目,编程实战课程 提供大量前端小练习。

常见问题

Q:const 声明的对象为什么还能改属性?
A:const 只禁止"重新赋值",不禁止"修改内容"。对象、数组照样能改内部成员,只是不能让变量指向别的对象。

Q:为什么现在不推荐 var?
A:var 是函数级作用域加变量提升,容易在块外被意外读到或被重复声明覆盖,bug 难查。let/const 的块级作用域和暂时性死区更安全。

Q:什么时候该用 let 而不是 const?
A:只要这个变量后面会被重新赋值(比如循环计数器、状态切换),就用 let;一旦赋值就不再改,用 const。

Q:var、let、const 三者能混用吗?
A:语法上能,但团队规范通常统一"默认 const、次之 let、不用 var",混用只会让代码风格混乱,也不利于别人阅读。

Q:暂时性死区到底有什么用?
A:它强制你先声明再使用,避免因为变量提升拿到 undefined 而引发逻辑错误,让代码行为更可预测、更好调试。

0 人点赞