14

我正试图绕过关闭(那里有一个笑话),我遇到了这个:

(function () { /* do cool stuff */ })();

这是如何运作的?将函数放在括号中的目的是什么?为什么之后是空的括号?

4

7 回答 7

30

这样做的重点是,在很酷的东西中声明的任何变量都不会在全局命名空间中创建。javascript 中的任何函数都会创建这样的范围。假设您有一些要运行的 javascript。如果你这样做:

var b = 1; 
// stuff using b

而其他一些代码使用 b,它将获得您的剩余价值。(或者,更糟糕的是,如果其他代码在您的代码运行之前设置 b,然后尝试获取它的旧值,那么您同时会更改它。)

另一方面,如果你有这段代码,它声明然后调用 a 函数:

function a() { 
     var b = 1;
}

a();

稍后一些其他代码使用 b,它不会看到您的值,因为 b 是函数的本地。当然,问题在于您仍在创建一个全局名称 - 在这种情况下为“a”。所以,我们想要一个没有名字的函数——这就是你得到你描述的代码的原因。它声明一个没有名称的函数,然后调用它。

不幸的是,你不能只说:

function() { ... }()

因为这将被解析为函数声明语句,然后是语法错误。通过将函数声明包装在括号中,您会得到一个函数表达式,然后可以调用它。您可以像任何其他函数表达式(如上面的 a)一样调用它,使用第二组括号。例如,如果函数接受参数,您将在那里传递它们:

(function(a) { ... })(1)
于 2009-03-10T16:56:30.853 回答
6

这会创建一个函数,调用它,然后丢弃它。

如果你这样看可能会更清楚:

var throwaway = function(){
    // do cool stuff
};
throwaway();

这样做是为了创建一个私有命名空间。函数中的代码可以有函数和变量,不用担心与页面中加载的其他代码冲突。

于 2009-03-10T16:50:27.187 回答
2

我最近才看到这篇文章。这种类型的函数定义和调用称为自调用函数

(function(){  //code })();

函数内部的代码将在其定义后立即执行。

于 2011-03-18T05:15:02.090 回答
1

该构造意味着声明一个匿名函数并立即运行它。将代码放在函数体中的原因是因为您在其中定义的变量仍然是函数的本地变量,而不是全局变量。然而,在这个函数中定义的闭包仍然可以看到它们。

于 2009-03-10T16:49:51.227 回答
1

函数周围的括号清楚地表明该函数是一个表达式。后面的括号是对函数的调用。

请注意,该函数没有名称。

于 2009-03-10T16:49:52.583 回答
1

一种闭包方法是将变量传递给函数:

(function($, var_1, var_2) {
    // use JQuery, var_1 and var_2 as local variables
})($, var_1, var_2);
于 2015-08-14T11:42:49.330 回答
0

将函数声明放在括号内会创建一个表达式,其计算结果为其中的匿名函数。因此,第一个括号计算为一个函数。

最后的“空括号”调用定义的函数,因此“//do cool stuff”立即执行。

这是一种即时执行代码的方法,同时也将变量保持在全局范围之外。

然而,这里说明的内容与闭包无关——至少不是直接的。闭包是关于在父函数已经退出后维护词法范围。

于 2009-03-10T16:50:39.463 回答