This question has already been answered:

var add_the_hendlers = function(node) { var i; for(i = 0; i < node.length; i++) { node[i].onclick = function() { console.log(i) } } } 

The problem is that console.log always returns the last increment, that is, on the page for example 3 diva, and when you click on them, 3 is always displayed, I know that you need to use closures, they say there is a reference to the variable, but why in this case so?

Reported as a duplicate by Grundy , Abyx , VenZell , cyadvert , user194374 members Jan 15 '16 at 17:43 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

    3 answers 3

     var add_the_hendlers = function(node) { var i; for(i = 0; i < node.length; i++) { (function(j) { node[j].onclick = function() { console.log(j) }; })(i); } } 

    In this case, the variable will be copied to the scope of the closure. At the same time the context will remain true (unlike bind )

    • one
      the classic solution :-) ideally, it would be worth changing the name of the parameter, otherwise now too much i :-D - Grundy
    • Yes, I am just for him. I think this is not the case where bind needed, the more the question is similar to those that are given at the interview, usually there expect such an answer. Changed) - Aleksander K.
    • For general knowledge, bind will do just fine, but I would not have done this but on the first parameter - Grundy
     for(var i = 0; i < node.length; i++) { node[i].onclick = function(event) { console.log(+this,event.target); }.bind(i); } 
    • one
      bad decision: i in this will become an object, not a primitive number - Grundy
    • Horrible. It can be turned into the number of one symbol - Darth
    • Of course :-) if you know that there will be an object, and not count on a primitive :-) - Grundy
    • In addition, in your case, the link to the element you clicked is lost - Grundy
    • one
      arguments[0].target (added to the answer) - Darth

    Because at the time of clicking on an element, you have already passed the for loop and i became equal to 3, therefore at the time of the click you see the last increment. Use the .bind function to save the desired context.

     var add_the_hendlers = function(node) { var i; for(i = 0; i < node.length; i++) { node[i].onclick = function() { console.log(this); }.bind(i); } } 
    • one
      the code is incorrect - at the time of execution i = already equal to 3, therefore there is no sense in assigning 3 to the variable x :-D - Grundy
    • I am sorry, corrected the code. - DStrokov
    • one
      console.log (this); will output an object, not a primitive. The same flaw that was in the next answer. In order not to repeat, it is better to push it as a parameter - Grundy
    • one
      In addition, in your case, the link to the item itself is clicked - Grundy
    • It agree, it is not necessary to erase this, especially this this object and to try to appropriate to it simple value - the bad approach. - Aleksander K.