小编典典

循环中的函数(返回另一个函数)如何工作?

javascript

我一直在尝试为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);

我设法根据需要对其进行了调整,并使alert(i)正常工作,但是如果有人可以确切解释以上代码的作用,我将不胜感激。


阅读 326

收藏
2020-05-01

共1个答案

小编典典

当您将功能分配给单击处理程序时,将创建一个闭包。

基本上,当您嵌套函数时会形成一个闭包,内部函数即使在其父函数已经执行后,也可以引用其外部封装函数中存在的变量。

在执行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),该值存储在外部闭包中,并且在click事件触发时执行内部函数。

我使用以下代码段解释闭包(以及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
2020-05-01