循环中的函数(返回另一个函数)如何工作? [英] How does a function in a loop (which returns another function) work?
问题描述
我一直在尝试为动态创建的a"事件的 onclick
事件分配一个函数.JavaScript 中的标签.所有标签都是在循环中创建的,如下所示:
I've been trying to assign a function to onclick
event of a dynamically created "a" tag in JavaScript. All of the tags are created in a loop as follows:
for ( var i = 0; i < 4; i++ )
{
var a = document.createElement( "a" );
a.onclick = function( ) { alert( i ) };
document.getElementById( "foo" ).appendChild( a );
}
所有四个链接的警报值始终为4".很明显.在谷歌搜索时,我发现了一个显示以下代码片段的帖子:
The alerted value for all four links is always "4". Pretty obvious. When googling I came across a post that shows the following code snippet:
a.onclick = (function(p, d) {
return function(){ show_photo(p, d) }
})(path, description);
我设法根据我的需要对其进行了调整,并使 alert( i ) 正常工作,但如果有人能准确解释上述代码的作用,我将不胜感激.
I managed to tweak it for my needs and got the alert( i ) thing to work correctly but I'll appreciate if someone could explain exactly what the above code does.
推荐答案
当您将函数分配给点击处理程序时,闭包 已创建.
When you assign the function to the click handler, a closure is created.
基本上,当您嵌套函数时会形成一个闭包,即使在其父函数已经执行之后,内部函数也可以引用其外部封闭函数中存在的变量.
Basically a closure is formed when you nest functions, inner functions can refer to the variables present in their outer enclosing functions even after their parent functions have already executed.
在执行点击事件时,处理程序引用 i
变量具有的最后一个值,因为该变量存储在闭包中.
At the time that the click event is executed, the handler refers to the last value that the i
variable had, because that variable is stored on the closure.
如您所见,通过包装点击处理函数以接受 i
变量作为参数,并返回另一个函数(基本上是创建另一个闭包),它按您的预期工作:
As you noticed, by wrapping the click handler function in order to accept the i
variable as an argument, and returning another function (basically create another closure) it works as you expect:
for ( var i = 0; i < 4; i++ ) {
var a = document.createElement( "a" );
a.onclick = (function(j) { // a closure is created
return function () {
alert(j);
}
}(i));
document.getElementById( "foo" ).appendChild( a );
}
当你迭代的时候,实际上创建了4个函数,每个函数在创建时存储了一个对i
的引用(通过传递i
),这个值存储在外部闭包和内部函数在点击事件触发时执行.
When you iterate, actually create 4 functions, each function store a reference to i
at the time it was created (by passing i
), this value is stored on the outer closure and the inner function is executed when the click event fires.
我使用以下代码段来解释闭包(以及 curry),我认为一个简单的例子可以更容易地理解这个概念:
I use the following snippet to explain closures (and a very basic concept of curry), I think that a simple example can make easier to get the concept:
// a function that generates functions to add two numbers
function addGenerator (x) { // closure that stores the first number
return function (y){ // make the addition
return x + y;
};
}
var plusOne = addGenerator(1), // create two number adding functions
addFive = addGenerator(5);
alert(addFive(10)); // 15
alert(plusOne(10)); // 11
这篇关于循环中的函数(返回另一个函数)如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!