Andy Hume 差不多 gave 答案,我只是想补充一些细节。
使用此构造,您正在创建一个具有自己的评估环境或闭包的匿名函数,然后您立即对其进行评估。这样做的好处是您可以访问在匿名函数之前声明的变量,并且可以在此函数中使用局部变量,而不会意外覆盖现有变量。
var 关键字的使用非常重要,因为在 JavaScript 中,默认情况下每个变量都是全局变量,但是使用该关键字可以创建一个新的 词法作用域 变量,也就是说,它在两个大括号之间之间的代码可见。在您的示例中,您实际上是在为 YUI 库中的对象创建短别名,但它具有更强大的用途。
我不想给你留下一个代码示例,所以我在这里放一个简单的例子来说明一个闭包:
var add_gen = function(n) {
return function(x) {
return n + x;
};
};
var add2 = add_gen(2);
add2(3); // result is 5
这里发生了什么?在函数 add_gen 中,您正在创建另一个函数,它将简单地将数字 n 添加到其参数中。诀窍是在函数参数列表中定义的变量充当词法范围的变量,就像用 var 定义的变量一样。
返回的函数定义在 add_gen 函数的大括号之间,因此即使在 add_gen 函数之后它也可以访问 n 的值已经执行完毕,这就是为什么在执行示例的最后一行时会得到 5。
借助词法范围的函数参数,您可以解决因在匿名函数中使用循环变量而引起的“问题”。举个简单的例子:
for(var i=0; i<5; i++) {
setTimeout(function(){alert(i)}, 10);
}
“预期”结果可能是从零到四的数字,但您会得到四个五的实例。发生这种情况是因为 setTimeout 和 for 循环中的匿名函数使用 very same i 变量,所以当函数被评估时,i 将是 5。
您可以通过使用问题中的技术以及函数参数是词法范围这一事实来获得天真的预期结果。 (我在other answer 中使用过这种方法)
for(var i=0; i<5; i++) {
setTimeout(
(function(j) {
return function(){alert(j)};
})(i), 10);
}
通过立即评估外部函数,您将在每次迭代中创建一个名为 j 的完全独立变量,i 的当前值将被复制 到这个变量中,所以你会得到第一次尝试时天真预期的结果。
我建议您尝试了解http://ejohn.org/apps/learn/ 的优秀教程,以更好地了解闭包,这是我学到的非常非常多的地方。