安迪休姆几乎给出了答案,我只想添加更多细节。
使用此构造,您将创建一个具有自己的评估环境或闭包的匿名函数,然后您立即对其进行评估。这样做的好处是您可以访问匿名函数之前声明的变量,并且您可以在此函数中使用局部变量而不会意外覆盖现有变量。
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功能,因此将有机会获得valueñ即使add_gen函数执行完毕,这就是为什么执行的例子的最后一行时,你会得到5。
借助词法作用域的函数参数,您可以解决在匿名函数中使用循环变量引起的“问题”。举个简单的例子:
for(var i=0; i<5; i++) {
setTimeout(function(){alert(i)}, 10);
}
“预期”结果可能是从 0 到 4 的数字,但您会得到四个 5 的实例。发生这种情况是因为 setTimeout 和 for 循环中的匿名函数使用了相同的 i变量,所以当函数被评估时,i将是 5。
您可以通过使用问题中的技术以及函数参数在词法范围内获得天真的预期结果。(我在另一个答案中使用了这种方法)
for(var i=0; i<5; i++) {
setTimeout(
(function(j) {
return function(){alert(j)};
})(i), 10);
}
通过对外部函数的立即评估,您将在每次迭代中创建一个名为j的完全独立的变量,并且i的当前值将被复制到该变量中,因此您将获得第一次尝试时天真地预期的结果。
我建议您尝试了解http://ejohn.org/apps/learn/上的优秀教程以更好地理解闭包,这是我学到的非常多的地方。