编程语言
首页 > 编程语言> > javascript-为什么在循环中将.onclick动态添加到img元素时,需要返回function()?

javascript-为什么在循环中将.onclick动态添加到img元素时,需要返回function()?

作者:互联网

此解决方案有效,但是我不明白第二个“ return function()”的作用是什么?

for (var i = 0; i < photos.length; i ++) {
    img.onclick = (function(photo) {
        return function() {
            hotLink(photo); //window.location = '/pics/user/' + photo.user_id;  
        };  
    })(photos[i]);

另外,为什么我必须包含(photos [i]);在末尾?

以前,我有这个,onclick总是链接到最后一张照片[i].

  for (var i = 0; i < photos.length; i ++) {
      img.onclick = function() {
          window.location = 'pics/user/' + photo.user_id
      };
  }

解决方法:

当您执行此操作时(假设有一张照片= photos [i],您在问题中遗漏了该位置):

img.onclick = function() { window.location = 'pics/user/' + photo.user_id };

函数内部的变量photo与函数外部的变量是相同的变量.它不是在定义函数时获取变量当前值的快照.它只是对同一变量的引用.周围的循环在每次迭代时都会更改该变量的值,但是不会每次都创建一个新变量;它正在重复使用相同的.因此,您生成的所有函数均引用完全相同的变量-唯一的一张照片.

当任何人实际单击图像并调用该函数时,循环早已终止,并且照片已脱离主程序的作用域,但它仍存在于内存中,因为所有这些功能仍对其进行引用.他们会发现它仍然指向列表中的最后一项,因为那是分配给它的最后一项.

因此,您需要为每个onclick函数赋予其自己的变量,该变量一旦创建就不会更改.由于Javascript没有块作用域,因此在Javascript中执行此操作的方法是调用函数并将值作为参数传递.在函数内部声明的函数参数和变量(与上面非工作示例中的photo相对,该照片在函数内部使用,但在函数外部声明)在每次调用函数时都会重新创建.当将photo声明为功能参数时,每个onclick都会获得其自己的副本,其他任何内容都无法修改,因此当有人最终单击该图像时,它仍然具有正确的值.

如果使用静态函数生成器函数,可能会更清楚;确实没有理由进行内联的声明和调用操作.您可以在循环外声明一次:

function makeOnclick(somePhoto) {
    return function() { hotlink(somePhoto); }
}

然后循环主体可以做到这一点:

img.onclick = makeOnclick(photo)

您正在调用makeOnclick并将照片作为参数传递. makeOnclick函数被声明为在很远的地方,即使您希望它也不能直接使用照片;它根本看不到该变量.相反,它所具有的只是其局部参数somePhoto-每次调用makeOnclick时都会将其创建为一个全新的变量.它在调用时使用photo的值进行了初始化,但这只是一个副本,因此当在下一次循环迭代中更改photo时,somePhoto的特定实例将保持不变.当下一次迭代调用makeOnclick时,它将创建somePhoto的新实例,并将其初始化为photo的新值,依此类推.因此,即使makeOnClick返回的内部函数继承了somePhoto变量,该变量也是专门为makeOnClick实例创建的;这些返回的函数中的每个函数都有其自己的私有somePhoto.

上面的工作代码以略有不同的方式做完全相同的事情.与其在循环之外一次声明makeOnclick函数并多次调用它,不如在每次循环中将其重新声明为一个匿名函数,然后立即调用它.这段代码:

img.onclick = (function(x) { blah(x); })(photo);

与此相同:

function foo(x) { blah(x); }
img.onclick = foo(photo);

无需为函数命名.通常,在JavaScript中:

(function (x,y,z) { doSomething(x,y,z); })(a,b,c);

与此相同:

function callDoSomething(x,y,z) { doSomething(x,y,z); }
callDoSomething(a,b,c);

该函数没有名称,并且没有保存在任何地方;它在调用后就消失了.

因此,每次在循环中声明onclick-generator函数并立即立即调用它是很简洁的,但是效率却不高.

标签:javascript-events,html,javascript
来源: https://codeday.me/bug/20191201/2079486.html