eventlistener中的JavaScript闭包

时间:2014-10-07 01:28:33

标签: javascript closures

<button>test</button>
<button>test</button>
<button>test</button>
<button>test</button>
<button>test</button>
<script>
var nodes = document.getElementsByTagName('button');
function clicked(i){
    console.log('pass');

    // Closure
    // return function(){
    //  console.log(i);
    // }

}
for (var i = 0; i < nodes.length; i++) {
   nodes[i].addEventListener('click', clicked(i));
}
</script>

我试着对js闭包有充分的理解,上面的函数添加了甚至是按钮的监听器。它控制台日志'通过'5次,然后点击按钮时什么都不做。但如果我取消注释闭包位(return),console.log将回显i,但不记录'pass'。我确实找到了相关的答案,但我不明白为什么关闭onclick没有记录'传递'字符串,当点击按钮而不是注销

How do JavaScript closures work?

2 个答案:

答案 0 :(得分:2)

您在这里做的是直接调用函数clicked,而不是将其设置为事件处理程序。

  

我不明白为什么关闭onclick没有记录通过&#39;单击按钮时的字符串,而不是注销i。

好吧,你的关闭是

return function(){
  console.log(i);
}

为什么要记录i以外的任何内容?

创建此闭包的函数应记录&#34;传递&#34;页面初始化期间五次(因为你在循环中调用了五次,每次记录一行并返回闭包)。

您可以使用bind

nodes[i].addEventListener('click', clicked.bind(nodes[i], i));

这将为您提供i作为函数的参数,以便您可以执行

console.log("pass", i);

答案 1 :(得分:0)

试图回答问题的原始问题......

  

但我不明白为什么关闭onclick没有记录通过&#39;串   当点击按钮而不是注销i

回到你的代码,没有注释掉的部分......

<button>test</button>
<button>test</button>
<button>test</button>
<button>test</button>
<button>test</button>
<script>
    var nodes = document.getElementsByTagName('button');
    function clicked(i) {
        console.log('pass');

         //Closure
         return function(){
          output(i);
         }

    }
    function output(i) {
        alert('The value of the closure i for this button is: '+i);
    }
    for (var i = 0; i < nodes.length; i++) {
        nodes[i].addEventListener('click', clicked(i));
    }
</script>
<style>
    html {
        counter-reset: button-count -1;
    }

    button:after {
        content: ' ' counter(button-count);
        counter-increment: button-count;
    }
</style>

(我还添加了一些额外的帮助解释)

当您在for loop中初始化事件侦听器时,您将clicked(i)返回值作为要在{{{{}上发生单击时调用的函数指针传递1}}。 在原始代码中,返回值是对 匿名函数 的引用,定义为:

node[i]

所以这是你单击按钮i时执行的内容 - 而不是function(){ console.log(i); } clicked仅在clicked期间执行。由于for loop,您将看到控制台中每个按钮的传递一次。

匿名函数 的词汇范围包含其包含函数for loop的范围,因此参数clicked为< em> <范围 匿名函数 。每次i终止时,在clicked期间,会在参数for loop上创建单独的 结束 ,并保留它{&lt; 1}}。该特定电话的价值。

在上面的代码中,我创建了一个名为output的函数,它接收参数i,所以这个

i
单击按钮i时调用

...:function(){ output(i); } 上也有一个闭包。

我还添加了一些CSS样式来为按钮编号。