一个循环中的函数(返回另一个函数)是如何工作的? [英] How does a function in a loop (which returns another function) work?

查看:161
本文介绍了一个循环中的函数(返回另一个函数)是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试在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。很明显。当Google搜索时,我遇到了一个显示以下代码片段的帖子:

  a.onclick =(function(p,d){ 
return function(){show_photo(p,d)}
})(path,description);

我设法根据我的需要调整它,并得到警报

解决方案

当您将函数分配给点击处理程序时, 关闭已创建。



基本上,当嵌套函数时,闭包就会形成,内部函数可以引用其外层函数中出现的变量,即使父函数已经执行之后。



在执行点击事件时,处理程序引用 i 变量的最后一个值,因为该变量存储在闭包上。

$正如你所注意到的,通过包装单击处理函数以接受 i 变量作为参数,并返回另一个函数创建另一个闭包)它按照您的期望工作:

  for(var i = 0; i< 4; i ++){
var a = document.createElement(a);
a.onclick =(function(j){//创建一个闭包
return function(){
alert(j);
}
} ));
document.getElementById(foo).appendChild(a);
}

迭代时,实际创建4个函数,每个函数存储一个 i 在创建时(通过传递 i ),这个值存储在外部闭包和内部函数



我使用下面的片段来解释闭包(以及一个非常基本的概念: curry ),我认为一个简单的例子可以更容易得到这个概念:

  //生成函数以添加两个数字的函数
function addGenerator(x){//存储第一个数字的闭包
return function(y) {//使添加
返回x + y;
};
}

var plusOne = addGenerator(1),//创建两个数字添加函数
addFive = addGenerator(5);

alert(addFive(10)); // 15
alert(plusOne(10)); // 11


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 );
}

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);

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.

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.

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 );
}

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.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆