总结

你能解释一下在JavaScript中封装匿名函数的语法背后的原因吗?为什么这样工作:(function(){})();但这不是:function(){}();?


我所知道的

在JavaScript中,像这样创建一个命名函数:

function twoPlusTwo(){
    alert(2 + 2);
}
twoPlusTwo();

你也可以创建一个匿名函数并将其赋值给一个变量:

var twoPlusTwo = function(){
    alert(2 + 2);
};
twoPlusTwo();

你可以通过创建一个匿名函数来封装一个代码块,然后将它包装在括号中并立即执行:

(function(){
    alert(2 + 2);
})();

这在创建模块化脚本时非常有用,可以避免由于潜在的冲突变量而使当前作用域或全局作用域混乱——就像Greasemonkey脚本、jQuery插件等情况一样。

现在,我明白为什么这是可行的了。括号将内容括起来,只公开结果(我相信有更好的方式来描述它),例如(2 + 2)=== 4。


我不明白

但我不明白为什么这不能同样有效:

function(){
    alert(2 + 2);
}();

你能给我解释一下吗?


当前回答

它们可以与参数一起使用

var x = 3; 
var y = 4;

(function(a,b){alert(a + b)})(x,y)

结果是7

其他回答

你也可以这样使用它:

! function() { console.log('yeah') }()

or

!! function() { console.log('yeah') }()

! - negative op将fn定义转换为fn表达式,因此,您可以立即使用()调用它。与使用0相同,fn def或void fn def

(function(){
     alert(2 + 2);
 })();

以上是有效的语法,因为括号内传递的任何内容都被视为函数表达式。

function(){
    alert(2 + 2);
}();

以上语法无效。因为java脚本语法分析器在函数关键字之后查找函数名,因为它没有找到任何东西,所以抛出一个错误。

在javascript中,这称为立即调用函数表达式(IIFE)。

为了使它成为一个函数表达式,你必须:

使用()将其括起来 在它前面放置一个void操作符 将它赋值给一个变量。

否则,它将被视为函数定义,然后你将无法通过以下方式同时调用/调用它:

 function (arg1) { console.log(arg1) }(); 

上面会给出错误。因为您只能立即调用函数表达式。

这可以通过以下几种方式实现: 方式1:

(function(arg1, arg2){
//some code
})(var1, var2);

方式2:

(function(arg1, arg2){
//some code
}(var1, var2));

方式3:

void function(arg1, arg2){
//some code
}(var1, var2);

方法4:

  var ll = function (arg1, arg2) {
      console.log(arg1, arg2);
  }(var1, var2);

以上所有操作都将立即调用函数表达式。

也许简短的回答是这样的

function() { alert( 2 + 2 ); }

是定义(匿名)函数的函数字面量。附加的()-对被解释为表达式,不需要在顶层,只需要字面量。

(function() { alert( 2 + 2 ); })();

在调用匿名函数的表达式语句中。

它们可以与参数一起使用

var x = 3; 
var y = 4;

(function(a,b){alert(a + b)})(x,y)

结果是7