/
Dealing with loops with create Closures

Dealing with loops with create Closures

So consider this problem. Let’s say you are constructing a menu and you need to set up some onclick events for the items in the menu.

So this is how one might set things up from first principles:

// Set up an array of items. var MENUitems = ["Company", "Product", "History", "Contact"]; var H = ''; for (var i=0; i < MENUitems.length; i++) { H+= "<div class='MENUitem'>" + MENUitems[i] + "</div>" } document.body.innerHTML = H;

And you might have some light styling:

.MENUitem { display: inline-block; padding: 5px; border: gray solid; margin: 2px; }

Then you set up some onclick handlers…

var MENUdom = document.querySelectorAll(".MENUitem"); // Get a NodeList for (var i=0; i < MENUitems.length; i++) { MENUdom[i].onclick = function(E){ console.log("Clicked " + MENUitems[i]);} }

But oh crap.

It’s doesn’t work as expected. Instead of forming a closure with the value i being 0, 1, 2 and 3, all the functions get the value of i defined as it is at the end of the loop - namely 4. And so we end up with:

A fix for this is to use a special keyword which is “let” instead of var. So you do this instead:

It’s kind of hacky workaround a language flaw in Javascript. Using the let keyword isn’t the only way to solve this problem. There are other workarounds possible. Read this article:

Loops, Closures and Ajax - David Young

For some other good ideas on how to solve this problem.

This video also touches on the concept of NodeList objects.

 

Related content

Why let is better than var
Why let is better than var
More like this
NodeList and HTMLCollection
NodeList and HTMLCollection
Read with this
Javascript Closure
Javascript Closure
More like this
How const can be helpful in modern Javascript
How const can be helpful in modern Javascript
Read with this
Javascript strings are immutable
Javascript strings are immutable
More like this
Move a div to an absolute position
Move a div to an absolute position
Read with this