Attempting to answer the original question as asked...
but i don't get why with closure onclick doesn't log the 'pass' string
when button clicked instead does log out the i
Go back to your code without the commented out section...
<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>
(I also added a little extra to help explain)
When you initialise the event listeners in the for loop, you are passing the return value of clicked(i) as the function pointer to be called when the click occurs on node[i].
In your original code, the return value is a reference to an anonymous function defined as:
function(){
console.log(i);
}
So this is what is executed when you click button i - not clicked.
clicked is only executed during the for loop. You will see pass one time for each button in the console due to the for loop.
The lexical scope for the anonymous function includes the scope of it's containing function clicked so the parameter i is in scope for the anonymous function. Each time clicked terminates, during the for loop, a separate closure is created on the parameter i, preserving it's value for that particular call.
In the code above, I created a function called output that receives a parameter i, so this
function(){
output(i);
}
... is called when you click button i: also having a closure on i.
I also added some CSS styling to number the buttons.