# Const/Let/Var
# 块级作用域和全局作用域
块级作用域(Block Scope)
块级作用域是指变量只在其声明的代码块内有效。在 JavaScript 中,块级作用域通常由花括号 {} 定义,如 if 语句、for 循环、函数等。
- let 和 const 声明的变量具有块级作用域
- 变量只在声明它的代码块内可访问
- 有助于避免变量名冲突和意外的变量修改
if (true) {
let blockScopedVar = "I'm only accessible inside this block";
console.log(blockScopedVar); // 正常工作
}
// console.log(blockScopedVar); // 错误:blockScopedVar 未定义
全局作用域(Global Scope)
全局作用域是指变量在整个程序中都可以被访问和修改。在 JavaScript 中,全局作用域通常指的是最外层的作用域。
- 在函数外部用 var 声明的变量,或直接赋值而不声明的变量,会成为全局变量
- 全局变量可以在程序的任何地方被访问
- 过多的全局变量可能导致命名冲突和代码维护困难
var globalVar = "I'm a global variable";
function testFunction() {
console.log(globalVar); // 可以访问全局变量
}
testFunction();
console.log(globalVar); // 在函数外也可以访问
理解这两种作用域对于编写清晰、可维护的代码至关重要。通常建议尽量使用块级作用域(let 和 const),以减少全局变量的使用,提高代码的可读性和可维护性。
变量提升(Hoisting)
变量提升是JavaScript中的一个特性,它会将变量和函数的声明移动到它们所在作用域的顶部。这意味着无论你在哪里声明变量或函数,它们都会被视为在当前作用域的开始处声明。
重要的是要注意,只有声明会被提升,而不是初始化。
变量提升示例:
console.log(x); // 输出:undefined
var x = 5;
console.log(x); // 输出:5
// 上面的代码等同于:
var x;
console.log(x); // 输出:undefined
x = 5;
console.log(x); // 输出:5
在这个例子中,var x 的声明被提升到了作用域的顶部,但赋值操作仍然在原来的位置。
函数提升示例:
sayHello(); // 输出:"Hello!"
function sayHello() {
console.log("Hello!");
}
在这个例子中,整个函数声明被提升到了作用域的顶部,因此我们可以在声明之前调用函数。
需要注意的是,let 和 const 声明的变量不会被提升。这是 ES6 引入这两个关键字的原因之一,以避免由变量提升引起的混淆和错误。
# Const/Let/Var
在 JavaScript 中,const、let 和 var 都用于声明变量,但它们有不同的作用域和使用场景:
1. Var
- 函数作用域或全局作用域
- 可以重复声明
- 存在变量提升
2. Let
- 块级作用域
- 不可重复声明
- 不存在变量提升
3. Const
- 块级作用域
- 不可重复声明
- 不存在变量提升
- 声明时必须初始化,且不能再次赋值(但对于对象和数组,其属性可以修改)
使用示例
// Var 示例
var x = 1;
if (true) {
var x = 2; // 同一个变量
console.log(x); // 输出 2
}
console.log(x); // 输出 2
// Let 示例
let y = 1;
if (true) {
let y = 2; // 新的变量,不同作用域
console.log(y); // 输出 2
}
console.log(y); // 输出 1
// Const 示例
const PI = 3.14159;
// PI = 3.14; // 错误:不能重新赋值
const obj = { name: "John" };
obj.name = "Jane"; // 可以修改对象属性
console.log(obj.name); // 输出 "Jane"
总结:
- 使用 const 声明不会被重新赋值的变量
- 使用 let 声明可能会被重新赋值的变量
- 避免使用 var,因为它可能导致作用域混淆