循环中的函数(返回另一个函数)是如何工作的?
我一直在尝试为JavaScript中的动态创建的“a”标签的onclick事件分配一个函数。所有标签均按以下方式创建:循环中的函数(返回另一个函数)是如何工作的?
for (var i = 0; i < 4; i++)
{
var a = document.createElement("a");
a.onclick = function() { alert(i) };
document.getElementById("foo").appendChild(a);
}
所有四个链接的警报值始终为“4”。很明显。谷歌搜索时,我遇到了一个帖子,显示下面的代码片段:
a.onclick = (function(p, d) {
return function(){ show_photo(p, d) }
})(path, description);
我设法调整它为我的需求,并得到了警报(我)的东西才能正常工作,但我会很感激,如果有人可以解释不清楚上面的代码做了什么。
,创建一个closure。
基本上,当您嵌套函数时会形成闭包,内部函数可以引用其外部函数中存在的变量,即使在其父函数已经执行后也是如此。
在执行click事件时,处理程序引用i
变量的最后一个值,因为该变量存储在闭包中。
正如你注意到,通过包装,以接受i
变量作为自变量的点击处理函数,并返回另一个功能(基本上创建另一个关闭),它的工作原理像您期望:
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
),该值存储在外部闭包中,并且在点击事件触发时执行内部函数。
我用下面的代码片段来解释关闭(和curry一个很基本的概念),我认为,一个简单的例子可以让更容易得到的概念:
// 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
泰勒,我为你高兴,我会让你完成,但这篇文章是所有时间中最好的。 – Tarik 2009-10-12 06:21:34
难怪你有42k点:) – 2009-10-12 07:49:13
有一天,人们会忘记Kanye West,就像我一样,所有提到他的模因会变得粗鲁和有点奇怪。 – RandomInsano 2010-06-23 15:01:35
没有太多细节,它实质上是通过将实例变量包装在一个立即执行的函数中,并将其传递给当单击元素时被执行的函数来创建副本。
把它看成是这样的:
function() { alert(i); } // Will expose the latest value of i
(function(I) { return function() { alert(I); }; })(i); // Will pass the current
// value of i and return
// a function that exposes
// i at that time
所以每次循环过程中,你实际上是执行返回一个功能与变量的当前值的函数。
其中,如果您想象一下你在你的循环,你正在创建一个可以看作4个独立的功能4个锚..
function() { alert(0); };
function() { alert(1); };
function() { alert(2); };
function() { alert(3); };
我会考虑寻找到的范围和封闭的JavaScript,如果你沿着这条道路走下去,不明白到底发生了什么事情,你可能会遇到来自意外行为的巨大问题。
感谢您的解释。这是一个很好的黑客 - 或者是它在JavaScript中完成的方式? – Amarghosh 2009-10-12 06:21:01
当触发onclick事件,匿名函数被调用,它指的是在循环中使用的相同的变量i
和其持有的i
的最后一个值,即4
该溶液至你的问题是使用函数返回一个功能:当您分配功能到单击处理
a.onclick = (function(k) {return function() { alert(k); }; })(i);
嗨,你能告诉我,为什么它警报“4”?它不应该是“2”吗?谢谢。 – Tarik 2009-10-12 06:39:11
for(var i = 0; i 2009-10-12 07:49:56
不,它离开我为3 – 2009-10-12 08:26:50