Friday 13 July 2012

Not just a matter of style

One could think that using a traditional for loop to iterate an array vs using the (relatively) new forEach method is just a matter of style, but I just realized today how handy the second approach comes for a rather particular case.

In this old post where I pondered about the usage of closures inside loops in C# and JavaScript, we could see how convoluted properly doing it in JavaScript could be, having to define an extra function. However, using the forEach method, as we already need a function for the iteration body, it seems pretty much more natural, just look the code below:


var buttons = [
 {text: "Open"},
 {text: "Save"},
 {text: "Exit"}
];

//------------------------------------------------
//this is the wrong way to do it, all closures trap the same "i" variable, so in the end, the value is 3 for all of them
for (var i=0; i<buttons.length; i++){
 buttons[i].click = function(){
  console.log(this.text + " is button " + i);
 };
}
buttons[0].click(); //prints 3
buttons[1].click(); //prints 3

//------------------------------------------------
//this options was fine, but the code is not too clean
for (var i=0; i<buttons.length; i++){
 buttons[i].click = (function(){
  var j = i;
  return function(){
   console.log(this.text + " is button " + j);
  }
 }());
}
buttons[0].click();  //prints 0
buttons[1].click();  //prints 1

//------------------------------------------------
//I bet this is much cleaner than the above
buttons.forEach(function(button, index){
 button.click = function(){
  console.log(this.text + " is button " + index);
 };
});
buttons[0].click(); //prints 0
buttons[1].click(); //prints 1

No comments:

Post a Comment