为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

喵喵时光机 2019-09-21 15:25:08
我一直在尝试为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)正常工作,但是如果有人可以确切解释以上代码的作用,我将不胜感激。
查看完整描述

3 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

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


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


在执行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


查看完整回答
反对 回复 2019-09-21
?
湖上湖

TA贡献2003条经验 获得超2个赞

无需赘述,这实际上是通过将实例变量包装在立即执行的函数中并将它们传递回单击元素时将要执行的函数中来创建实例变量的副本。


这样想:


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来研究范围和闭包,就好像您走这条路并且不完全了解正在发生的事情一样,您可能会因意外行为而遇到大量问题。


查看完整回答
反对 回复 2019-09-21
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

触发onclick事件时,将调用匿名函数,该匿名函数引用i循环中使用的相同变量,并保留的最后一个值(i即4)。


您问题的解决方案是使用返回函数的函数:


a.onclick = (function(k) {return function() { alert(k); }; })(i);


查看完整回答
反对 回复 2019-09-21
  • 3 回答
  • 0 关注
  • 410 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号