用于循环增量的JavaScript表现奇怪

我有以下JS:

for ( var i = 1; i <= 2; i++ ) { $(window).load(function() { alert(i); }); } 

当页面加载时,它会按预期两次发出警报。 但奇怪的是,两个警报的价值都是3。 我希望第一个警报的i值为1,第二个警报的值为2。 是什么原因造成的? 先感谢您!

更新#1

如果我需要将函数放在循环中,因为我想使用数字增量作为选择器,该怎么办? 这个问题有解决方案吗? 这就是我的意思

 for ( var i = 1; i <= 2; i++ ) { $( '.element-' + i + ' .span' ).click( function( event ) { $( '.element-' + i + ' ul' ).show( 'fast' ); }); } 

点击函数未被触发,因为我们已经知道i = 3 。 我希望单击.element-1 .span.element-2 .span时触发click函数。 有解决方法吗?

您正在使用捕获的变量i创建闭包。 当window.load事件处理程序执行时,循环已完成,此变量的值为3。

 for ( var i = 1; i <= 2; i++ ) { $(window).load((function(iter) { return function() { alert(iter); }; })(i)); } 

更新:

在您的代码中,您直接将匿名函数指定为$(window).load的事件处理程序。 这个函数将循环迭代器变量i作为变量绑定,并且,当该函数执行时, i的值是所有先前执行的代码所分配的值, i完成的循环 - 当i变为3时终止。

我的代码可以重写:

 function getEventHandler(iter) { return function() { alert(iter); }; } for ( var i = 1; i <= 2; i++ ) { $(window).load(getEventHandler(i)); } 

getEventHandler返回一个函数(它变成$(window).load事件处理程序)。 返回的函数将iter参数与getEventHandler执行时此参数的值绑定 - 每次执行时。 在循环中,我们在每次循环迭代中立即使用i的当前(变化)值调用getEventHandler

我假设你真正想做的是在$(window).load函数中使用for循环,如下所示:

 $(window).load(function() { for (var i = 0; i <= 2; i++) { alert(i); } }); 

这将在加载window后运行for循环。


解释为什么您的警报中有3

此图表说明了当前警报中获得3警报的原因:

 TIME | The for loop is begun (a = 0) | The load event on the window is handled by the specified function the load | function itself does not run | i is incremented (i++) now i = 1 | The load event on the window is handled again | i is incremented (i++) now i = 2 | The load event on the window is handled again | i is incremented (i++) now i = 3 | The condition of the for loop fails so execution is discontinued | | The window is loaded | Each of the callbacks is run and at this point i = 3 so 3 is alerted each | time