let,const,var关键字
let,const,var都存在变量提升
它们都存在变量提升但是稍微有点不同
- var变量声明会被提升到作用域的顶部,并且会被初始化为 undefined
- let 和 const:变量声明也会被提升到作用域的顶部,但不会被初始化,会进入暂时性死区,在变量声明之前访问 let 或 const 声明的变量会抛出 ReferenceError
console.log(x1)console.log(x2)var x1 = 1let x2 = 2
let与const都会产生块级作用域而var不会
1. 什么是块级作用域(Block Scope)?
块级作用域 是指由一对花括号 {} 包裹的代码块(如 if、for、while、switch 或单独的 {} 块), 块内部定义的变量,仅在该代码块内有效,外部无法访问。
在 JavaScript 中,块级作用域是通过 let 和 const 关键字实现的,而传统的 var 声明的变量是函数作用域(Function Scope),不具备块级作用域的特性。
2. 问题:块级作用域的作用是什么?
(1) 避免变量污染(防止变量泄漏)
- var的问题: 在 for 循环或 if 块中声明的变量会泄漏到外部,可能造成意外覆盖。
for (var i = 0; i < 3; i++) {setTimeout(() => console.log(i)); // 输出 3, 3, 3(因为 var i 是全局的)}
- let 的解决方案:
for (let i = 0; i < 3; i++) {setTimeout(() => console.log(i)); // 输出 0, 1, 2(每次循环都是新的块级作用域)}
(2) 更清晰的代码逻辑
- 在 if、for、while、switch 等块中声明的变量,不会影响外部作用域,减少命名冲突。
if (true) {let temp = "临时变量";console.log(temp); // 正常使用}console.log(temp); // 报错:temp is not defined(不会污染外部)
3. 支持 const 声明不可变变量
- const 必须初始化,且不能重新赋值,适用于常量声明。
const PI = 3.14159;PI = 3.14; // 报错:Assignment to constant variable
- 注意:const 定义的对象或数组仍然可以修改内部属性(只是不能重新赋值)。
const obj = { name: "Alice" };obj.name = "Bob"; // 允许修改属性obj = {}; // 报错(不能重新赋值)
为什么:因为通过 const 声明的引用类型数据存储的是引用类型的指针(内存地址),而不是实际的值本身,所以可以修改对象/数组内部的值,但不能重新赋值(改变这个指针)(再深入一点说,就是对于引用类型数据来说,const只能保证存储的指针不变,无法保证保存该引用数据的堆内存的数据不变)
总结
- 避免意外全局变量:var 容易因变量提升和穿透块导致变量泄漏。
- 更符合直觉的作用域:let/const 的作用域更接近其他编程语言(如 C、Java)。
- 提高代码可维护性:减少变量冲突,使代码逻辑更清晰。