Skip to content

Instantly share code, notes, and snippets.

@0xgdr
Created November 16, 2019 12:36
Show Gist options
  • Select an option

  • Save 0xgdr/7b8ea9564748a7a31367ffddd3df5199 to your computer and use it in GitHub Desktop.

Select an option

Save 0xgdr/7b8ea9564748a7a31367ffddd3df5199 to your computer and use it in GitHub Desktop.
Understanding Closures In JavaScript :: 2016-03-29

This example shows how you create a closure in JavaScript it uses an alert function that can be incremented and reused/passed around.

The Problem

The following code will alert the number 3 three times. You may have expected it to alert 0,1,2 (don't forget JavaScript is zero based).

var a = {};
for (var i = 0; i < 3; i++) {
    a[i] = function() {
    alert(i);
};

a[0](); // 3
a[1](); // 3
a[2](); // 3

What happens to cause this behaviour is the loop runs once and sets the a[i] property to the function which will alert i:

a[i] = function() {
    alert(i);
};

The loop repeats 3 times (because of i < 3). Then the function stored at each property of a gets run (using a[0]()) etc. The i argument passed into alert is now 3 because the loop has run three times and the variable iin global scope is set to 3.

a[0](); // 3
a[1](); // 3
a[2](); // 3

The Solution

To get around this you can set an IFFE around the internal function:

var a = {};
for (var i = 0; i < 3; i++) {
    (function(j) {
    a[j] = function() {
    alert(j);
   };
}(i));

a[0](); // 3
a[1](); // 3
a[2](); // 3

What this does is provide a closure around the j variable which means that the loop will iterate three times using i then the value of i is passed into the IFFE as the parameter j for each iteration. Because a function closure is now provided by the IFFE around the variable j it will not be global and therefore is set to the loop iteration number as you would expect resulting in:

a[0](); // 0
a[1](); // 1
a[2](); // 2

If you enjoyed this post I have a collection of JS learning examples CodePen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment