2

我熟悉执行函数的 IIFE 方式:

(function(){
    //stuff
}());
//immediately invoked, parsed as an expression

通过这种方式,我可以通过像任何其他对象一样声明它来为函数分配名称:

var theFunction = function(){
    //stuff
}
//can be executed with theFunction();

但是今天我看到两者结合起来是这样的:

var theFunction = (function(){ 
    //stuff
}());

这有什么作用,或者它可以提供什么优势?

4

3 回答 3

9

您所展示的内容不是带有名称的 IIFE(确实存在)。它是一个保存IIFE返回值的变量。


一个真正有名字的 IIFE 是这样的:

(function myName (){
    // code here...
}());

IIFE 上的名称有两个用途:

  1. 供自己参考。如果函数想要(递归地)调用自己,它可以使用该名称(而不是arguments.callee,这在严格模式下不起作用)。

  2. 它有助于调试,因为它会在堆栈跟踪中显示函数的名称。

于 2013-08-21T19:17:37.037 回答
4

theFunction 将设置为 IIFE 的返回值。这通常被称为模块模式

这是允许对象具有在全局空间中不可用的私有变量的好方法,但对于模块自己的函数仍然可见,并且因此是命名代码的最佳方法之一。

例如,这是一个带有 getter 和 setter 示例的简单私有变量。

很容易将其修改为仅允许设置某些值,从而限制对属性的访问。

var module = (function(){
  var x = {};
  var private = 2;

  x.setPrivate = function(val) {
     private = val;
  }

  x.getPrivate = function() {
    return private;
  }

  return x;

}());

正如其他人指出的那样,这与命名的 IIFE 不同,如果您想从内部引用该函数,则可以使用它

(function foo(){
  //recursive foo call
  foo();
}()):
于 2013-08-21T19:19:50.967 回答
2

这会将 IIFE 的结果分配给变量。如果您需要一堆辅助变量来初始化变量但又不想污染命名空间,这将非常有用。或者它使您能够构建可以访问其他辅助非全局“私有”函数的函数。

于 2013-08-21T19:19:39.197 回答