1. 说说var、let、const之间的区别

张开发
2026/4/20 12:00:07 15 分钟阅读

分享文章

1. 说说var、let、const之间的区别
一、先给面试官一个结论版var、let、const都可以用来声明变量但它们主要区别在于作用域、变量提升、重复声明、暂时性死区、是否允许重新赋值这几个方面。var是函数作用域存在变量提升可以重复声明let和const是块级作用域也会提升但受暂时性死区影响不能重复声明其中let可以重新赋值const必须在声明时初始化且不能重新赋值。这段特别适合开场。二、核心区别有哪些1作用域不同var函数作用域var声明的变量作用域是当前函数如果不在函数内就是全局作用域。if (true) { var a 1 } console.log(a) // 1因为var不受块级作用域限制。let/const块级作用域块级作用域就是{}内有效。if (true) { let b 2 const c 3 } console.log(b) // ReferenceError console.log(c) // ReferenceError面试加分说法let和const的块级作用域能更好地控制变量可见范围减少变量污染这也是它们比var更适合现代开发的重要原因。2变量提升不同三者都会被提升但表现不一样。var的提升var声明会被提升并且初始化为undefined。console.log(a) // undefined var a 10等价于var a console.log(a) a 10let/const的提升它们也会提升但不会在声明前初始化处于暂时性死区TDZ。console.log(b) // ReferenceError let b 10console.log(c) // ReferenceError const c 20什么是暂时性死区从作用域开始到变量正式声明之前这段区域内不能访问该变量。{ // TDZ 开始 let x 1 // TDZ 结束 }面试亮点严格来说let和const不是“没有提升”而是“提升了但不能在声明前访问”因为存在暂时性死区。这句话非常加分。3是否允许重复声明var可以重复声明var a 1 var a 2 console.log(a) // 2let/const不能在同一作用域重复声明let b 1 let b 2 // SyntaxErrorconst c 1 const c 2 // SyntaxError这能减少很多低级错误。4是否允许重新赋值var允许var a 1 a 2let允许let b 1 b 2const不允许重新赋值const c 1 c 2 // TypeError5const是否真的“不可变”这是面试高频点。答案是const保证的是变量绑定关系不可变不是值本身绝对不可变。如果const声明的是基本类型值不能改如果声明的是对象或数组对象内部属性仍然可以改。const obj { name: Tom } obj.name Jack // 可以 console.log(obj.name) // Jack但是不能重新赋值obj {} // TypeError面试加分说法const不能保证深层不可变它只是保证变量引用地址不变。如果要真正不可变还需要配合Object.freeze或不可变数据方案。6初始化要求不同var/let可以只声明不赋值。var a let bconst声明时必须初始化。const c // SyntaxError因为它后续不能重新赋值所以一开始就必须给值。7全局声明时与window的关系不同var在全局作用域下通过var声明的变量会成为全局对象的属性浏览器中通常是window。var a 1 console.log(window.a) // 1let/const不会挂到全局对象上。let b 2 const c 3 console.log(window.b) // undefined console.log(window.c) // undefined这个点说出来会显得你理解更深入。三、经典面试场景题1for循环里var和let的区别这是非常高频的问题。varfor (var i 0; i 3; i) { setTimeout(() { console.log(i) }, 100) } // 3 3 3因为var没有块级作用域循环结束后i已经变成 3三个回调拿到的是同一个i。letfor (let i 0; i 3; i) { setTimeout(() { console.log(i) }, 100) } // 0 1 2因为let在每次循环中都会形成一个新的块级绑定。面试加分说法let在for循环里不仅是块级作用域更关键的是每次迭代都会创建新的词法环境所以异步回调能拿到当次循环的值。这句话很强。四、为什么现在更推荐let和const你不能只背区别还要说工程意义。可以这样说在现代 JavaScript 开发中一般不再推荐使用var因为它的函数作用域、可重复声明和声明提升机制容易引发变量污染和难以排查的问题。let和const引入块级作用域后变量生命周期更清晰代码也更安全。通常的使用建议默认优先用const变量后续需要重新赋值时再用let尽量不用var这句很适合面试中收尾。五、面试怎么回答更精彩你可以按下面的结构说。标准版回答var、let、const都可以用来声明变量它们的核心区别主要有五点作用域、变量提升、暂时性死区、重复声明以及是否允许重新赋值。首先var是函数作用域不受块级作用域限制而let和const是块级作用域这能更好地避免变量污染。其次var会发生变量提升并且在声明前访问时值是undefinedlet和const其实也会提升但因为存在暂时性死区在声明前访问会报错。再者var允许重复声明而let和const在同一作用域下不允许重复声明。在赋值方面let可以重新赋值const不可以而且const声明时必须初始化。另外要注意const不是说值完全不可变而是变量绑定不能变。如果是对象内部属性仍然可以修改。从工程实践来说现在一般推荐默认使用const只有在明确需要修改变量时才使用let尽量避免使用var。因为let和const的块级作用域和更严格的约束能让代码更安全、可维护性更好。这段回答是比较完整、成熟的。六、如果想答得更高级可以补充这几个点1“let/const没有变量提升”这句话不严谨更严谨的说法是它们也会提升只是不能在声明前访问因为存在暂时性死区。2const不等于对象不可变如果面试官追问一定要能说清不能改引用但可以改对象内部属性3循环中的闭包问题可以主动提到let在循环中为每次迭代创建独立绑定这是它在异步场景中比var更可靠的一个典型体现。七、对比表总结区别点varletconst作用域函数作用域块级作用域块级作用域变量提升是值为undefined是但有 TDZ是但有 TDZ暂时性死区没有有有重复声明允许不允许不允许重新赋值允许允许不允许声明时初始化不必须不必须必须挂到全局对象会不会不会八、精简版面试回答如果时间比较短可以这样答var、let、const的主要区别在于作用域和赋值规则。var是函数作用域存在变量提升声明前访问得到undefined而且可以重复声明let和const是块级作用域也会提升但因为有暂时性死区声明前访问会报错并且不能重复声明。其中let可以重新赋值const不可以而且const声明时必须初始化。另外const保证的是引用不变不代表对象内容完全不可修改。在实际开发里我一般默认用const需要修改时用let尽量避免使用var。九、一句话总结面试官真正想听的是你是否知道三者的核心区别你是否理解TDZ、变量提升、块级作用域你能不能说出const不等于绝对不可变你有没有结合实际开发习惯来回答

更多文章