let和const均为块级作用域、不提升、不可重复声明,区别仅在能否重新赋值;var因函数作用域和变量提升易引发闭包、泄露等问题,应避免使用。
直接说结论:let 和 const 都是块级作用域、不提升、不可重复声明,区别只在「能否重新赋值」——let 允许后续赋值,const 要求声明时初始化且禁止重新赋值(注意:不是「不可变」)。
var 替代 let?var 的函数作用域和变量提升(hoisting)常导致意料外的行为,比如循环中闭包问题、条件块内变量泄露到外层。
常见错误现象:
for (var i = 0; i console.log(i), 0); } 中输出三个 3,而非 0、1、2
if (false) { var x = 1; } console.log(x); // undefined,但不会报错 —— 变量声明被提升,赋值没执行实操建议:
var
var 应视为技术债,ESLint 规则 no-var 值得开启const 声明的对象/数组能改内容吗?能。只要不重新赋值给该变量名,对象属性增删、数组元素 push/pop 都合法。所谓「不可重新赋值」,仅指不能做 myObj = {} 或 myArr = [] 这类操作。
示例:
const obj = { a: 1 };
obj.a = 2; // ✅ 允许
obj.b = 3; // ✅ 允许
obj = { c: 4 }; // ❌ TypeError: Assignment to constant variable.
const arr = [1];
arr.push(2); // ✅ 允许
arr[0] = 99; // ✅ 允许
arr = [3, 4]; // ❌ 同样报错
容易踩的坑:
const = 「不可变」,结果在函数里修改了传入的 const 参数对象,引发隐蔽副作用const 声明函数表达式(const fn = () => {})是安全的,但若函数内部依赖外部可变状态,仍可能产生非纯行为let,什么时候选 const?优先用 const,仅当明确需要后续重新赋值时才用 let。这不是风格偏好,而是代码自文档化和防错手段。
使用场景判断:
const:函数参数、模块顶层配置、DOM 引用(const btn = document.getElementById('x'))、for...of 循环变量(for (const item of list))let:计数器(let i = 0)、需要多次重赋值的状态变量(let currentUser = null)、while 循环条件变量性能与兼容性影响:
let/const 优化已很成熟最易被忽略的一点:块级作用域的「块」是指 {} 包裹的任意代码块,包括 if、for、try/catch 内部,而不仅限于函数。这意味着 const 在 if (true) { const x = 1; } 里声明的 x,在 if 外访问会直接报 ReferenceError,而不是 undefined —— 这个严格性恰恰是调试友好的关键。