好吧,您可以在循环中保留 for 的上下文,因为 for 中的所有内容实际上与开始时声明的函数处于相同的上下文中。
让我们以 Frits 的例子为例,但首先让我们先让 JSLint 完全满意(减去循环错误中调用的函数)。
/*global console*/
var my_func, i, list;
for (i = 0; i < list.length; i+= 1) {
my_func = function (i) {
console.log(i);
};
my_func(i);
}
请注意,每次你迭代循环,你重新声明my_func函数。这不酷!为什么要一遍又一遍地重新声明相同的函数?
提前声明,像这样:
/*global console*/
var my_func, i, list;
my_func = function (i) {
console.log(i);
};
for (i = 0; i < list.length; i+= 1) {
my_func(i);
}
成功。现在您不必为每次迭代创建一个函数。而且,由于 JSLint 通过将所有 var 声明推到顶部来帮助您实现,您仍然可以获得相同的上下文。
编辑: 作为@Flame points out,您不必使用jQuery each 提前声明函数,并且可以使用匿名函数,但提前声明也不错,尤其是如果您要在多个 each 调用中重用逻辑。主要的收获是理解 1.) 早期声明实践仍然有优势,以及 2.) jQuery 仍然会向您的函数发送参数(这里,我们称之为 index),尽管 JSLint 会不(也不应该)抱怨eachs (jQuery sauce here) 中使用的匿名函数。
如果您习惯于匿名 $.each(function() {}); 构造,最初会有点不直观,但它同样简单。
/*global alert, $ */
$( "li" ).each(function( index ) {
alert( index + ": " + $(this).text() );
});
...变成...
/*global $, alert */
var fnOutside = function(index) {
alert( index + ": " + $(this).text() );
};
$( "li" ).each(fnOutside);
这可能会造成短暂的混淆,因为函数调用没有参数,但 jQuery 将“index”参数推送到函数。如果你想省略命名,你可以抓住上下文 arguments 数组,看看它仍然被推到那里。
Fiddle-ige
也就是说,for 构造不会创建新的闭包。这可能让你担心。没问题!