<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没有记录'传递'字符串,当点击按钮而不是注销我。
答案 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样式来为按钮编号。