2010-05-21 120 views
1

我搜索,但无法找到这个看似简单的问题的答案,所以...Javascript功能问题

假设我有一个循环,我需要设置回调。我的回调函数如下:

function callback(var1) { // code } 

现在我的循环是这样的:

for(//condition) 
{ 
    var x = something_different_each_time; 
    document.getElementById('foo').addEventListener('click', function() { callback(x); }, false); 
} 

现在看起来即使循环运行n次,匿名函数只有一次编译 - 因此每个回调调用都使用相同的参数调用(即使每次循环中的x都会变化)。

我必须在这里失踪的东西..任何帮助非常感谢! :)

+1

类似的问题:http://stackoverflow.com/questions/1734749/ http://stackoverflow.com/questions/643542/ http://stackoverflow.com/questions/1582634/ HTTP: //stackoverflow.com/questions/1331769/ http://stackoverflow.com/questions/1552941/ http://stackoverflow.com/questions/750486/ http://stackoverflow.com/questions/ 933343/ http://stackoverflow.com/questions/1579978/ http://stackoverflow.com/question s/1413916/ – CMS 2010-05-21 07:57:40

+1

这是一个综合清单@CMS。用“闭包”和“循环”标记这些问题会很好,所以它们都可以通过简单的搜索进行链接。 – Anurag 2010-05-21 08:01:56

+1

完成,所有问题都被标记为“javascript”,“closures”和“loops”。这里的链接 - http://stackoverflow.com/questions/tagged/javascript+closures+loops – Anurag 2010-05-21 08:07:50

回答

2

的问题是,for语句块不创建一个新的范围,为的是,x变量属于它的封闭范围,所有匿名函数是指同一个变量...

使用另一个函数来创建一个新的词汇环境来保存在每次迭代的x值:

for(/*condition*/) { 
    var x = something_different_each_time; 
    document.getElementById('foo').addEventListener('click', function() { 
    return function(y) { 
     callback(y); 
    }; 
    }(x), false); 
} 
+0

我想你错过了你的匿名函数表达式的一些大括号。 – deceze 2010-05-21 08:05:57

+2

@deceze:不,只有当函数位于函数表达式和函数声明之间可能引起语法歧义的地方时,才需要括号,在这种情况下,函数位于函数调用的参数列表中, (函数(fn){fn();})(function(){alert('hi');});' – CMS 2010-05-21 08:10:34

+0

@deceze:也许是一个更好的例子:'var foo = function(){return'bar'; }();'函数调用没有问题...'foo ==='bar';' – CMS 2010-05-21 08:17:20

1

你应该在调用你的回调函数之前计算x!

for(//condition) 
{ 
    //var x = something_different_each_time; 
    document.getElementById('foo').addEventListener('click', function() { 
    var x = something_different_each_time; 
    callback(x); }, false); 
} 
+0

这不是真的问题。不管怎么说,还是要谢谢你。 – ragebiswas 2010-05-21 09:23:17

0

是的,x将引用相同的变量在封闭的范围,而且由于该功能后执行,它的最后一个值是x。试试这个:

.addEventListener(
    'click', 
    (function (i) { 
     return function() { callback(i); } 
    })(x), 
    false 
); 

这创建了一个关闭,当前值为x锁定在里面。