函数与类提升

js/function_hoisting2026-08-24 19:46:25

函数提升

在 JavaScript 中,函数提升(Function Hoisting)是指在代码执行之前,函数声明会被提升到其所在作用域的顶部。这意味着你可以在函数声明之前调用该函数。

函数声明提升

函数声明会被提升到其所在作用域的顶部,因此你可以在函数声明之前调用该函数。

例如:

// 可以在函数声明之前调用函数
console.log(add(2, 3));  // 输出 5

// 函数声明
function add(a, b) {
    return a + b;
}

在这个示例中,函数 add 的声明被提升到作用域的顶部,因此你可以在声明之前调用它。

函数表达式不提升

函数表达式不会被提升,这意味着你不能在函数表达式之前调用该函数。

例如:

try {
    console.log(subtract(5, 3));  // 会抛出 TypeError: subtract is not a function
} catch (e) {
    console.error(e);
}

// 函数表达式
const subtract = function(a, b) {
    return a - b;
};

在这个示例中,函数表达式 subtract 不会被提升,因此在声明之前调用它会导致错误。

提升的作用域

函数提升只在其所在的作用域内有效。例如,在函数内部声明的函数只会在该函数的作用域内被提升。

function outer() {
    console.log(inner());  // 输出 "Hello from inner"

    function inner() {
        return "Hello from inner";
    }
}

outer();

在这个示例中,inner 函数的声明被提升到 outer 函数的顶部,因此你可以在 inner 函数声明之前调用它。

类提升

在 JavaScript 中,类提升(Class Hoisting)与函数提升不同。虽然类声明在其所在的作用域内被提升,但类本身不会被初始化,直到执行到类声明的那一行代码。这意味着你不能在类声明之前访问或实例化该类。

类声明提升但不初始化

类声明会被提升到其所在作用域的顶部,但类不会被初始化。

类声明具有与 let 和 const 相同的 暂时性死区 限制。在类声明之前访问或实例化类会导致 ReferenceError。

例如类似声明:

try {
    const instance = new MyClass();  // 会抛出 ReferenceError: Cannot access 'MyClass' before initialization
} catch (e) {
    console.error(e);
}

// 类声明
class MyClass {
    constructor() {
        this.name = "MyClass";
    }
}

const instance2 = new MyClass();  // 正常工作
console.log(instance2.name);  // 输出 "MyClass"

在这个示例中,类 MyClass 的声明被提升到作用域的顶部,但在声明之前访问或实例化该类会导致 ReferenceError。

类表达式不提升

与函数表达式类似,类表达式也不会被提升。这意味着你不能在类表达式之前访问或实例化该类。

例如:

try {
    const instance = new MyClass();  // 会抛出 ReferenceError: MyClass is not defined
} catch (e) {
    console.error(e);
}

// 类表达式
const MyClass = class {
    constructor() {
        this.name = "MyClass";
    }
};

const instance2 = new MyClass();  // 正常工作
console.log(instance2.name);  // 输出 "MyClass"

在这个示例中,类表达式 MyClass 不会被提升,因此在声明之前访问或实例化该类会导致 ReferenceError。

参考

提升
https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting

本页目录