š¾ 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
ā¬ ļø Previous capture (2021-11-30)
-=-=-=-=-=-=-
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); }); });