Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Understanding JavaScript Closures

DZone's Guide to

Understanding JavaScript Closures

Closures can be quite tricky to understand, especially for beginners. They are one of the most powerful features of JavaScript but they cannot be properly exploited without understanding them.

· Web Dev Zone ·
Free Resource

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Closures are objects that contain a function and a reference to the environment in which the function was created. They are a language construct, which allows developers to preserve the state of the variables and thus prolong the scope.

Let's look at a basic example:

Here, the function reference variable newFunc references to both the function that alerts and to its closure. The inner function sayHello() has access to the containing functions variables.

Module Patterns

In JavaScript, we can simulate private methods using closures - private methods that are only accessible by other functions created within that closure. Functions can be attached to an object and returned outside of that function call. This establishes a public API and only the functions defined within that public API will have access to those hidden functions.

Let's look at the following example:

var myCounter = (function() {
  var count = 0;
  //private
  function sum(val) {
    count += val;
  }
  return {
    //public
    increment: function() {
      sum(1);
    },
    value: function() {
      return count;
    }
  };  
})();
myCounter.increment();
myCounter.increment();
console.log(myCounter.value()); //2

Here, the function sum() cannot be accessed from outside the wrapper function myCounter(). The returned object has references to function sum(), which in turn has access to the "private" variable count.

Using Closures in Loops

Consider the following example.

for(var i = 1; i <= 3; i++) {
   setTimeout(function() {
       console.log(i);
   },1);
}

When we run the above code, we get the following output:

4

4

4

Here, var defines the variable globally or locally to an entire function regardless of block scope.

The problem is that the closure scope for each anonymous function at each iteration of the loop points to the same variable, the same location in memory. All of them point to the same variable, i. When 1-millisecond passes and the callback functions begin to run they all look for the variable i on their outer function scope. All the callback functions share the same outer function scope that has a single i variable which is now 4, where 4 is the number that finally breaks the loop.

One of the ways to solve this problem is to make use of let introduced in ES6. We can write the above code as follows:

for(let i = 1; i <= 3; i++) {
   setTimeout(function() {
       console.log(i);
   },1);
}

Here, let defines the variable in block level scope. When we run this code, we get the following output:

1

2

3

Wrapping Up

Closures are powerful programming constructs for achieving binding between code and data in a more flexible and out-of-bounds manner. They make code more compact and readable and promote functional re-use.

Deploying code to production can be filled with uncertainty. Reduce the risks, and deploy earlier and more often. Download this free guide to learn more. Brought to you in partnership with Rollbar.

Topics:
web dev ,javascript ,closures ,web application development

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}