# 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,因为它可能导致作用域混淆