跳到主要内容

JavaScript 提升

提示
  1. Hoisting的定义:在JavaScript中,Hoisting是一种行为,它允许在声明函数或变量之前使用它们。
  2. 变量Hoisting:使用var关键字声明的变量会发生Hoisting,而使用letconst则不会。在Hoisting中,仅声明被提升,初始化不会被提升。
  3. 函数Hoisting:函数声明可以在声明之前调用,但函数表达式不适用于此规则,使用函数表达式之前必须先声明。

在JavaScript中的**提升(Hoisting)**是指在声明函数或变量之前就可以使用它们的一种行为。例如,

// 在声明前使用test
console.log(test); // undefined
var test;

上述程序可以运行,输出结果将是undefined。上述程序的行为相当于:

// 在声明前使用test
var test;
console.log(test); // undefined

由于变量test只是声明了而没有赋值,因此它被赋予了undefined值。

如果你想了解更多关于变量的信息,请访问 JavaScript Variables

注意:在提升过程中,虽然看起来声明在程序中向上移动了,实际发生的是函数和变量声明在编译阶段被添加到内存中。

变量提升

在变量和常量方面,关键字var是可以提升的,而letconst则不允许提升。

例如,

// 程序显示值
a = 5;
console.log(a);
var a; // 5

在上面的示例中,变量a在声明之前被使用。程序可以运行并显示输出5。程序的行为如下:

// 程序显示值
var a;
a = 5;
console.log(a); // 5

然而在JavaScript中,初始化不会被提升。例如,

// 程序显示值
console.log(a);
var a = 5;

输出

undefined;

上述程序的行为如下:

var a;
console.log(a);
a = 5;

只有声明被移动到编译阶段的内存中。因此,变量a的值是undefined,因为在初始化之前就打印了a。

此外,当变量在函数内部使用时,该变量只会被提升到函数的顶部。例如,

// 程序显示值
var a = 4;

function greet() {
b = "hello";
console.log(b); // hello
var b;
}

greet(); // hello
console.log(b);

输出

hello
Uncaught ReferenceError: b is not defined

在上述示例中,变量b被提升到函数greet的顶部,并成为局部变量。因此,b只能在函数内部访问。b不会成为全局变量。

要了解更多关于局部和全局变量的信息,请访问 JavaScript Variable Scope

注意:在提升中,变量声明只能在其直接作用域内被访问。

如果使用let关键字声明变量,则该变量不会被提升。例如,

// 程序显示值
a = 5;
console.log(a);
let a; // error

输出

Uncaught ReferenceError: Cannot access 'a' before initialization

使用let时,必须首先声明变量。

函数提升

在声明之前可以调用函数。例如,

// 程序打印文本
greet();

function greet() {
console.log("Hi, there.");
}

输出

Hi, there.

在上述程序中,函数greet在声明之前被调用,程序显示输出。这是由于提升所致。

然而,当函数作为表达式使用时,会发生错误,因为只有声明被提升。例如;

// 程序打印文本
greet();

let greet = function () {
console.log("Hi, there.");
};

输出

Uncaught ReferenceError: greet is not defined

如果在上述程序中使用了var,错误将会是:

Uncaught TypeError: greet is not a function

注意:通常,其他编程语言如Python、C、C++、Java不会进行提升。

提升可能会在程序中引起不希望的结果。最好在使用变量和函数之前先声明它们,以避免提升。

在变量的情况下,使用let比使用var更好。