šŸ’¾ Archived View for danieljanus.pl ā€ŗ blog ā€ŗ en ā€ŗ 2011 ā€ŗ 05 ā€ŗ 15 ā€ŗ a-quirk-with-javascript-closures ā€ŗā€¦ captured on 2023-01-29 at 15:54:02. Gemini links have been rewritten to link to archived content

View Raw

More Information

ā¬…ļø Previous capture (2021-11-30)

-=-=-=-=-=-=-

A quirk with JavaScript closures

IĀ keep running into this obstacle every now and then. Consider this example:

> q = []
[]
> for (var i = 0; i < 3; i++)
    q.push(function() { console.log(i); });
> q[0]()
3

IĀ wanted an array of three closures, each printing aĀ different number toĀ the console when called. Instead, each prints 3 (or, rather, whatever the value of the variable ā€œiā€ happens toĀ be).

IĀ am not exactly sure about the reason, but presumably this happens because the ā€œiā€ in each lambda refers toĀ the variable ā€œiā€ itself, not toĀ its binding from the creation time of the function.

One solution is toĀ enforce the bindings explicitly on each iteration, like this:

for (var i = 0; i < 3; i++)
  (function(v) {
    q.push(function() { console.log(v); });
  })(i);

Or use Underscore.js [1], which is what IĀ actually do:

_([1,2,3]).each(function(i) {
  q.push(function() { console.log(i); });
});

Links

[1]