JavaScript 起重(Hoisting)

JavaScript 是一门动态语言,允许在运行时声明和修改变量。但是,在理解 JavaScript 变量声明和作用域时,起重(Hoisting)的概念非常重要。

什么是起重?

起重是指将变量和函数声明提升到其作用域的顶部。这意味着,无论您在何处声明变量或函数,它们都会被视为在当前作用域的顶部声明。

变量起重

假设我们有以下代码:

--------------------- -- ---------
--- ------- - --------

尽管我们在使用 console.log() 之前声明了 message 变量,但输出的却是 undefined。这是因为在代码执行期间,var message 的声明被提升到了作用域的顶部,但它的值并没有被赋值,因此输出结果是 undefined

以下是一个更详细的例子,演示了变量起重可以如何影响作用域:

-------- ----- -
  --------------------- -- ---------
  --- ------- - --------
-
------

在这个例子中,我们声明了一个名为 foo 的函数,并在内部声明了一个名为 message 的变量。即使我们在 console.log() 之前声明了 message 变量,输出的结果仍然是 undefined。这是因为在函数执行期间,JavaScript 引擎会将变量声明提升到函数的顶部。因此,我们的代码实际上是这样运行的:

-------- ----- -
  --- --------
  --------------------- -- ---------
  ------- - --------
-
------

函数起重

与变量一样,函数也可以被起重。假设我们有以下代码:

------ -- -------
-------- ----- -
  ---------------------
-

在这个例子中,我们调用了 foo() 函数,然后再声明该函数。尽管这看起来不合理,但实际上这段代码能够正常工作,因为函数声明被提升到了作用域的顶部。

与变量不同,函数起重不仅仅是将函数声明提升到作用域的顶部。它还会将整个函数体提升到顶部,而不仅仅是函数名称和参数。这意味着您可以在函数声明之前调用该函数。

以下是一个更详细的例子:

------ -- -------
-------- ----- -
  ---------------------
-
------ -- --------------- --- -- --- -------
--- --- - ---------- -
  ---------------------
--

在这个例子中,我们首先声明了一个名为 foo 的函数,并在之后调用了它。然后,我们尝试使用相同的模式声明变量 bar,并将它设置为一个函数。但是,当我们尝试在 bar() 函数调用之前调用 bar() 时,会报错。

这是因为变量起重不同于函数起重。在变量起重中,只有变量声明被提升,而变量的值仍然是 undefined。但是,在函数起重中,整个函数体都被提升了。因此,如果您尝试访问未定义的函数,则会引发 ReferenceError

结论

起重是 JavaScript 变量和函数声明的一种行为,它将变量和函数声明提升到作用域的顶部。虽然起重可以使代码更加简洁易读,但过多地依赖于它可能导致代码难以理解和维护。建议始终在作用域的顶部声明变量和函数来避

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/12059