Hoisting 如何影响函数声明和表达式?
主题
JavaScript
在GitHub上编辑
TL;DR
JavaScript 中的 Hoisting 意味着函数声明在编译阶段被移动到其包含作用域的顶部,使其在整个作用域中可用。这允许您在代码中定义函数之前调用它。但是,函数表达式不会以相同的方式被 Hoisting。如果您尝试在定义函数表达式之前调用它,您将收到一个错误,因为保存函数的变量被 Hoisting,但其赋值没有被 Hoisting。
// Function declarationconsole.log(foo()); // Works finefunction foo() {return 'Hello';}// Function expressionconsole.log(bar()); // Throws TypeError: bar is not a functionvar bar = function () {return 'Hello';};
JavaScript 中的 Hoisting
函数声明
函数声明被 Hoisting 到其包含作用域的顶部。这意味着您可以在代码中定义函数之前调用该函数。
console.log(foo()); // Works finefunction foo() {return 'Hello';}
在上面的例子中,函数 foo
被 Hoisting 到其作用域的顶部,因此在定义之前调用 foo()
可以正常工作,没有任何问题。
函数表达式
另一方面,函数表达式不会以相同的方式被 Hoisting。保存函数的变量被 Hoisting,但其赋值没有被 Hoisting。这意味着如果您尝试在定义函数表达式之前调用它,您将收到一个错误。
console.log(bar()); // Throws TypeError: bar is not a functionvar bar = function () {return 'Hello';};
在这个例子中,变量 bar
被 Hoisting 到其作用域的顶部,但赋值 function() { return 'Hello'; }
没有被 Hoisting。因此,在赋值之前调用 bar()
会导致 TypeError
。
var
、let
和 const
之间的区别
在使用函数表达式时,注意 var
、let
和 const
之间的 Hoisting 行为差异也很重要。
var
:变量被 Hoisting 并使用undefined
初始化。let
和const
:变量被 Hoisting 但未初始化,如果在初始化之前访问,则会导致ReferenceError
。
console.log(baz); // undefinedvar baz = function () {return 'Hello';};console.log(qux); // ReferenceError: Cannot access 'qux' before initializationlet qux = function () {return 'Hello';};console.log(quux); // ReferenceError: Cannot access 'quux' before initializationconst quux = function () {return 'Hello';};