Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/450.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我能通过吗;新";addEventListener的匿名函数_Javascript_Events_Arguments_Anonymous Function - Fatal编程技术网

Javascript 我能通过吗;新";addEventListener的匿名函数

Javascript 我能通过吗;新";addEventListener的匿名函数,javascript,events,arguments,anonymous-function,Javascript,Events,Arguments,Anonymous Function,我使用这样的代码将参数传递给事件处理函数。但是,在这种特殊情况下,循环会导致问题。在所有activeVisual调用中,只有最后的linkTags[i]是可访问的。这与传递参数的匿名函数在整个循环中是一个相同的事实有关 for (var i = 0; i < linkTags.length; i++) { addCrossEvent(linkTags[i], "click", launchLink); addCrossEvent(linkTags[i], "moused

我使用这样的代码将参数传递给事件处理函数。但是,在这种特殊情况下,循环会导致问题。在所有activeVisual调用中,只有最后的linkTags[i]是可访问的。这与传递参数的匿名函数在整个循环中是一个相同的事实有关

  for (var i = 0; i < linkTags.length; i++) {
    addCrossEvent(linkTags[i], "click", launchLink);
    addCrossEvent(linkTags[i], "mousedown", 
      function(evt) {
        activeVisual(evt, linkTags[i]);
      });
  }
for(var i=0;i
现在,我记得我尝试在匿名函数声明之前添加new,如下所示:

  for (var i = 0; i < linkTags.length; i++) {
    addCrossEvent(linkTags[i], "click", launchLink);
    addCrossEvent(linkTags[i], "mousedown", 
      new function(evt) {
        activeVisual(evt, linkTags[i]);
      });
  }
  // Function that provides pass of event handling parameters with separate copy in each loop
  function callbackHandler(index) {
    return function(evt) {
      activeVisual(evt, linkTags[index]);
    }
  }
  ...
  for (var i = 0; i < linkTags.length; i++) {
    ...
    addCrossEvent(linkTags[i], "mousedown", callbackHandler(i));
  }
for(var i=0;i
它不起作用。activeVisual从未被调用。有人能给我解释一下为什么,我怎样才能让它工作吗

更新最终解决方案

感谢下面的所有回复,我的工作代码现在如下所示:

  for (var i = 0; i < linkTags.length; i++) {
    addCrossEvent(linkTags[i], "click", launchLink);
    addCrossEvent(linkTags[i], "mousedown", 
      new function(evt) {
        activeVisual(evt, linkTags[i]);
      });
  }
  // Function that provides pass of event handling parameters with separate copy in each loop
  function callbackHandler(index) {
    return function(evt) {
      activeVisual(evt, linkTags[index]);
    }
  }
  ...
  for (var i = 0; i < linkTags.length; i++) {
    ...
    addCrossEvent(linkTags[i], "mousedown", callbackHandler(i));
  }
//在每个循环中提供事件处理参数传递和单独副本的函数
函数回调处理程序(索引){
返回函数(evt){
activeVisual(evt,链接标签[索引]);
}
}
...
对于(var i=0;i
您需要执行以下操作:

addCrossEvent(linkTags[i], "mousedown", 
      (function(i) {
          return function(evt) {
              activeVisual(evt, linkTags[i]);
          }
      )(i);
);
问题在于迭代器变量
i
在每次迭代时都会发生变化,并且传递了对它的引用,
i
的值不会被复制。以这种方式将其作为参数传递给包装函数,将产生一个副本,并在该特定迭代中接收实际值。

您需要执行以下操作:

addCrossEvent(linkTags[i], "mousedown", 
      (function(i) {
          return function(evt) {
              activeVisual(evt, linkTags[i]);
          }
      )(i);
);

问题在于迭代器变量
i
在每次迭代时都会发生变化,并且传递了对它的引用,
i
的值不会被复制。以这种方式将其作为参数传递给包装函数,将产生一个副本,并在该特定迭代中接收实际值。

为完整起见,以下是使用
new
的方法不起作用的原因说明:

当您使用
new
调用函数时,该函数将生成一个空对象(您可以使用
this
在函数内部引用该对象,该对象继承自函数原型)并返回它。
因此,实际上您并没有将函数作为回调处理程序传递,而是传递函数返回的对象

只要对象实现了,以便可用作事件处理程序,这就不是问题。如果这样做,您可以对代码进行一些修改:

  for (var i = 0; i < linkTags.length; i++) {
    addCrossEvent(linkTags[i], "click", launchLink);
    addCrossEvent(linkTags[i], "mousedown", 
      new (function(index) {
        this.handleEvent = function(evt) {
            activeVisual(evt, linkTags[index]);
        }
      })(i));
  }
也就是说,我发现使用立即函数返回函数更容易阅读,而且我认为使用函数作为事件处理程序而不是对象也更常见


为了完整起见,下面解释一下为什么您使用
的方式不起作用:

当您使用
new
调用函数时,该函数将生成一个空对象(您可以使用
this
在函数内部引用该对象,该对象继承自函数原型)并返回它。
因此,实际上您并没有将函数作为回调处理程序传递,而是传递函数返回的对象

只要对象实现了,以便可用作事件处理程序,这就不是问题。如果这样做,您可以对代码进行一些修改:

  for (var i = 0; i < linkTags.length; i++) {
    addCrossEvent(linkTags[i], "click", launchLink);
    addCrossEvent(linkTags[i], "mousedown", 
      new (function(index) {
        this.handleEvent = function(evt) {
            activeVisual(evt, linkTags[index]);
        }
      })(i));
  }
也就是说,我发现使用立即函数返回函数更容易阅读,而且我认为使用函数作为事件处理程序而不是对象也更常见


如果迭代器i变量是问题所在,那么它为什么不会在该行中引起问题addCrossEvent(linkTags[i],“click”,launchLink)?它是否仅通过引用传递给匿名函数?因为当您添加CrossEvent(linkTags[i],“click”,launchLink)时;每个循环的linkTags数组中都有值i,但当在事件上调用函数时,i有最后一个值,并且在循环中只有相同的位置array@avok00:在
addCrossEvent(linkTags[i],“click”,launchLink)
中,将
linkTags[i]
的值直接传递给函数。但是
activeVisual(evt,linkTags[i])在调用回调时计算,而不是在循环中。但是当调用回调时,循环已经完成,
i
有了它的最终值。顺便说一句,您缺少一个
}
来关闭立即数函数;)@avok00:它只是一个立即执行的函数(这就是为什么它看起来像
(function(index){…}(i))
捕获
i
的当前值(在我的示例中,在参数
index
中)。请记住,函数还可以访问“更高”范围内的变量(这是闭包的原理)在这里,立即函数(事件处理程序)返回的函数可以访问“包装器”函数的作用域,因此指向
索引
。您可以事先定义该函数,而不是创建即时函数,类似于我的对象示例。如果迭代器i变量是问题所在,那么它为什么不会在该行中引起问题addCrossEvent(linkTags[i],“click”,launchLink);?它是否仅通过引用传递给匿名函数?因为当您执行addCrossEvent(linkTags[i],“click”,launchLink)时,每个循环的linkTags数组中都有值i,但当在事件上调用函数时,i有最后一个值,并且在array@avok00:在
addCrossEvent(链接标签[i],“单击”,启动链接)
您可以将
linkTags[i]
的值直接传递给函数。但是
activeVisual(evt,linkTags[i]);
在回调为cal时会对回调中的值进行评估