使用立即调用函数的Javascript提升过程:为什么这个声明的函数在函数表达式之前没有运行?

时间:2015-03-12 15:27:48

标签: javascript jquery

代码:

var funcExpression = function(){
  alert("function expression");  
}();

(function declarFunc(){
  alert("declared func");  
})();

结果是首先运行Expression函数,导致警报 "function expression" ,并且声明的函数在第二个 "declared func" 运行。

我知道在提升过程中,声明的函数完全在其容器内提升并加载到内存中。但是函数表达式并没有被提升:它们保持在同一个地方,直到运行时才被加载到内存中(尽管指向函数表达式的变量被提升并设置为Undefined(请更正我,如果我有这个概念错了)

因为声明的函数在函数表达式赋值之上被提升,所以我希望首先执行声明的函数:导致警告 "declared func" 然后函数表达式之后执行:导致 "function expression" 的第二次提醒。

然而:它并没有达到我的预期。因此,它似乎与两个函数的立即调用有关。也许立即调用保持相同的顺序?也许在提升过程之后,代码看起来真的像这样:

var funcExpression = Undefined;

(function declarFunc(){
  alert("declared func");  
})

funcExpression = function(){
  alert("function expression");  
}();

(); // this executes declarFunc.  Maybe declarFunc is hoisted up 
    // but the invoking part stays in the same place?

1 个答案:

答案 0 :(得分:1)

反馈和其他研究后的解决方案

答案是这些函数的两个函数是函数表达式:

代码:

var funcExpression = function(){
  alert("function expression");  
}();

(function declarFunc(){
  alert("declared func");  
})();

所以declareFunc()看起来像一个声明的函数,但由于它被括在括号中,它会将其转换为命名的函数表达式。后面的括号会立即唤起这个函数表达式。

由于(function declarFunc(){...})()由于这些包装括号而转换为命名函数表达式,因此我无法在提升过程后显示代码的样子。这意味着在此命名函数范围之外,我们无法调用它。

示例:如果在执行declarFunc()这些功能后,它将返回错误:ReferenceError: Can't find variable: declarFunc.

如果我们确实想要运行此函数表达式,那么我们希望将函数表达式赋给变量:

var foo = function declarFunc(){
  alert("declared func");  
};

注意:如果我们查看控制台,我们会看到console.log(foo())将返回undefined,但该功能的操作仍会发生。只要知道如果没有指定return语句,它就会隐式返回undefined

现在我们可以使用foo().

多次调用该函数