我熟悉IIFE执行函数的方法:
(function(){
//stuff
}());
//immediately invoked, parsed as an expression
这种方式我只需通过声明它就像任何其他对象一样为函数指定一个名称:
var theFunction = function(){
//stuff
}
//can be executed with theFunction();
但是今天我看到这两个组合如下:
var theFunction = (function(){
//stuff
}());
这是做什么的,或者它可以提供什么优势?
答案 0 :(得分:8)
你所展示的是没有名称的IIFE(确实存在)。它是一个变量,用于保存IIFE的返回值。
具有名称的真实IIFE将是:
(function myName (){
// code here...
}());
在IIFE上使用名称是双重的:
供自我参考。如果函数想要自己调用(递归),它可以使用该名称(而不是arguments.callee
,这在严格模式下不起作用。)
它有助于调试,因为它会在堆栈跟踪中显示函数的名称。
答案 1 :(得分:4)
该函数将被设置为IIFE的返回值。这通常称为module pattern
这是一种允许对象拥有全局空间中不可用的私有变量但是模块自身函数仍然可见的私有变量的好方法,并且是将代码命名为a的最佳方法之一结果
例如,这是一个带有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();
}()):
答案 2 :(得分:2)
这将IIFE的结果分配给变量。如果您需要一堆辅助变量来初始化变量但不想污染命名空间,这可能非常有用。或者它使您能够构建可以访问其他辅助非全局“私有”函数的函数。