授课语音

掌握JS变量声明与提升的机理

JavaScript 中的变量声明和提升是理解代码执行顺序的重要部分。通过深入理解变量声明的机制,我们能够更好地掌握作用域、执行上下文以及代码的执行流程。


1. 变量声明

JavaScript 中的变量声明有三种方式:varletconst。这三种方式的区别在于作用域、提升和可变性等方面。

1.1 var 声明

  • var 是 JavaScript 中传统的变量声明方式,声明的变量具有函数作用域(如果在函数内部声明)或全局作用域(如果在函数外部声明)。
  • var 声明的变量会发生变量提升,即在变量声明之前就可以使用该变量。

1.2 let 声明

  • let 是 ES6 引入的变量声明方式,声明的变量具有块级作用域,即在代码块内有效。
  • let 声明的变量不会被提升到作用域的顶部,因此在声明之前使用该变量会导致 ReferenceError 错误。

1.3 const 声明

  • const 也是 ES6 引入的,声明的是常量,必须在声明时赋值,并且值不能修改。const 也具有块级作用域。
  • let 相似,const 声明的常量也不会发生提升。

2. 变量提升机制

JavaScript 中的变量提升指的是变量和函数声明会被“提升”到作用域的顶部。需要特别注意的是,提升是只对声明部分有效,而赋值部分不会提升。

2.1 var 的提升

  • var 声明的变量会被提升到作用域的顶部,但赋值不会被提升。
  • 如果在变量声明之前使用它,变量会被初始化为 undefined

2.2 letconst 的提升

  • letconst 声明的变量也会被提升,但它们不会被初始化为 undefined。在声明之前访问这些变量,会导致 ReferenceError 错误。
  • 这些变量处于“暂时性死区”(TDZ,Temporal Dead Zone)中,即在声明之前无法访问。

3. 代码案例:var 提升

示例代码

console.log(a); // 输出 undefined,因为变量 `a` 已被提升,但未赋值
var a = 10;
console.log(a); // 输出 10,赋值后变量 `a` 的值为 10

详细解释:

  • 在 JavaScript 中,var a = 10; 实际上会被提升为:

    var a; // 变量声明被提升
    console.log(a); // 输出 undefined
    a = 10; // 赋值在执行到这一行时发生
    
  • 因此,在变量 a 声明之前访问它会得到 undefined,而不是 ReferenceError


4. 代码案例:letconst 提升

示例代码(let

console.log(b); // 报错 ReferenceError: Cannot access 'b' before initialization
let b = 20;

示例代码(const

console.log(c); // 报错 ReferenceError: Cannot access 'c' before initialization
const c = 30;

详细解释:

  • letconst 声明的变量在提升时,并不会初始化它们的值,而是会进入一个“暂时性死区”。在这段时间内,访问这些变量会抛出 ReferenceError 错误。
  • 只有在执行到 let b = 20;const c = 30; 赋值操作时,变量才会被初始化并可正常访问。

5. 函数声明与提升

5.1 函数声明的提升

  • 函数声明会被提升到作用域的顶部,且可以在声明之前调用。

5.2 函数表达式的提升

  • 函数表达式(例如使用 varletconst 声明的函数)不会发生提升。

6. 代码案例:函数声明与函数表达式的提升

示例代码(函数声明)

myFunction(); // 输出 "Hello, World!"
function myFunction() {
  console.log("Hello, World!");
}

详细解释:

  • 由于函数声明会被提升,myFunction() 可以在函数声明之前调用。

示例代码(函数表达式)

myFunction(); // 报错 TypeError: myFunction is not a function
var myFunction = function() {
  console.log("Hello, World!");
};

详细解释:

  • 在使用 var 声明函数表达式时,函数名 myFunction 会被提升,但赋值部分不会,因此在调用时会抛出 TypeError

7. 总结

  • var:声明的变量会被提升,并初始化为 undefined
  • letconst:声明的变量会被提升,但不会初始化,访问时会导致 ReferenceError,它们存在于暂时性死区。
  • 函数声明:会被提升,可以在声明之前调用。
  • 函数表达式:不会被提升,调用时会报错。

理解这些变量声明和提升的机制,有助于我们避免常见的错误,提高代码的可维护性和执行效率。

去1:1私密咨询

系列课程: