JavaScript 变量提升是什么?

2025年3月17日 | 阅读 3 分钟

众所周知,变量声明是任何编程语言(如 C 语言C++ 等)的基本且重要的方面。然而,JavaScript 有一个叫做“变量提升”的微妙特性,它可能将看似完美的声明变成一个隐藏的 bug。

变量提升

JavaScript 中,变量提升是一种默认行为,即在执行程序代码之前,所有变量声明或函数声明都会被移到作用域的顶部。然而,这可以被认为是一种优势,因为所有函数和变量声明都会被放置在其作用域的顶部,无论它们在整个程序中的任何位置声明,甚至无论它们是全局声明还是局部声明。

由于 JavaScript 变量提升的概念,我们甚至可以在程序代码中定义函数定义之前调用一个函数。

简单来说,我们可以说在 JavaScript 中,我们可以在声明变量和函数之前使用它们,因为如上所述,JavaScript 编译器会在执行代码之前将所有变量和函数的声明移到其作用域的顶部,这样就不会出现任何错误。JavaScript 编译器在代码执行前,将所有变量和函数的声明移到其作用域顶部的这个概念就叫做变量提升。

注意:需要记住的重要一点是,在 JavaScript 中,只有函数声明和变量声明会被提升,而不是初始化。

让我们来理解一下这究竟是什么

变量声明和初始化的顺序通常是这样的:

1. 声明 -> 2. 初始化/赋值 -> 3. 使用

What is hoisting in JavaScript

示例

但正如我们所知,JavaScript 允许我们同时声明和初始化变量。这是最常见的模式之一。

输出

What is hoisting in JavaScript

注意:另一个需要记住的重要一点是,在后台,JavaScript 会先声明变量、函数,然后再初始化它们。然而,未声明的变量在 JavaScript 中直到为其赋值的代码执行之前都不存在。因此,当为任何未声明的变量赋值时,在赋值代码执行时,它们会被转换为全局变量。所以我们可以说所有未声明的变量都是全局变量。

示例

程序解释

在上面的程序中,我们使用 `function` 关键字创建了两个名为“codeHoist();”和“fun();”的函数。在“codeHoist();”的定义中,我们使用 `let` 关键字声明了变量“b”并将其赋值为 50。我们还有另一个变量“a”,我们将其声明为未声明并为其赋值 11。

在“fun();”函数的定义中,我们只是打印了两个变量的值。

在调用函数“fun();”时,它将打印我们在函数“codeHoist();”的定义中未声明的变量“a”的值,但它不会打印我们使用 `let` 关键字声明的变量的值。这是因为变量“a”的作用域被 JavaScript 本身更改为全局(或者我们可以说变量“a”被转换为全局变量),所以函数“fun();”能够打印变量的值。但是,函数“fun();”无法打印变量“b”的值,因为它使用了“let”关键字进行声明,因此其作用域被限制在函数定义内,对于任何外部函数都不可用。

输出

What is hoisting in JavaScript