23

Whats the main purpose of Closures in JS. Is it just used for public and private variables? or is there something else that I missed. I am trying to understand closure and really want to know what are the main advantages of using it.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
Jay
  • 313
  • 1
  • 5
  • 11
  • 3
    I would recommend reading http://jibbering.com/faq/notes/closures/ unless you are having trouble grasping the explanation. – meder omuraliev Jun 10 '11 at 17:26
  • This is a dead link now. There must be some great tutorials on the various kinds of closures, especially closed function call closures, but I could not find one quickly using a Web search. – David Spector Sep 25 '20 at 12:27

4 Answers4

13

Closures have to do with how javascript is scoped. To say it another way, because of the scoping choices (i.e. lexical scoping) the javascript designers made, closures are possible.

The advantage of closures in javascript is that it allows you to bind a variable to an execution context.

var closedIn = {};

var f = function(){
   closedIn.blah = 'blah'; // closedIn was just "closed in" because I used in the function, but it was defined outside the function.
}

in that example, you have a normal object literal called closedIn. It is accessed in a function. Because of that, javascript knows it has to bring closedIn everywhere it brings the function f, so it is available to f.

The this keyword is tricky. this is always a reference to the execution scope. You can capture the this of one context to use in another context as follows:

var that = this;
var f = function(){
    that.somethingOnThat();
   // `this` means the scope f, `that` means whatever 'this' was when defined outside of the function
}

This trick can be very useful somethings, if you are coding object oriented javascript and want a callback to have access to some external scope.

To quote from a Javascript book:

"Functions in JavaScript are lexically rather than dynamically scoped. This means that they run in the scope in which they are defined, not the scopee from which they are executed. When a function is defined, the current scope chain is saved and becomes part of the internal state of the function."

So the clear advantage is that you can bring any object (functions, objects, etc) along with the scope chain as far as is necessary. This is can also be considered a risk, because your apps can easily consume lots of memory if you are not careful.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
  • Regarding the quote from the book, it should be noted that the scope chain is capture when the function is defined, with the exception of the value of 'this'. 'this' is very dependent on how the function is executed. – Matt Jun 10 '11 at 18:17
  • As someone who is doing some heavy javascript single page application. I need to use closures to save "this" context ALL THE TIME. If you are using jquery for example when you bind a function to an event the "this" keyword is bound to the HTML element that triggered the event, changing the context inside. – Hoffmann Sep 12 '12 at 20:43
7

I think the best phrase to sum up the purpose of closures would be:

Data Encapsulation

With a function closure you can store data in a separate scope, and share it only where necessary.

If you wanted to emulate private static variables, you could define a class inside a function, and define the private static vars within the closure:

(function () {
    var foo;
    foo = 0;
    function MyClass() {
        foo += 1;
    }
    MyClass.prototype = {
        howMany: function () {
            return foo;
        }
    };
    window.MyClass = MyClass;
}());
Community
  • 1
  • 1
zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • That's not the purpose. The purpose is persistence of local scope. – Raynos Jun 10 '11 at 17:32
  • @Raynos, there is more than one purpose to closures. Persistence of scope is part of data encapsulation. I wouldn't even be so narrow as to say `local scope`. – zzzzBov Jun 10 '11 at 17:35
  • In my head all scope is local to something, so its all local. might aswell drop that and say scope. Your coding style is interesting. – Raynos Jun 10 '11 at 17:37
  • 1
    @Raynos, i consider `local scope` to be the innermost scope for a particular function. If multiple closures are used, you maintain scope within all of them, not just the innermost. – zzzzBov Jun 10 '11 at 17:40
3

Closures are necessary in javascript due to the fact that most API's that require callback functions (for instance, an "onclick" function) do not provide other mechanisms to send parameters to those callback functions (or to explicitly set the "this" pointer). Instead, you need to use closures to allow the callback to access variables in the "parent" function.

I personally wish that they weren't necessary, since they can be hard to understand, make for hard to read code (it's not always clear what exactly is in scope), and make for weird bugs. Instead I wish there was a standard for callbacks that allowed you to send parameters, etc. But I accept that I am in the minority in this view.

rob
  • 9,933
  • 7
  • 42
  • 73
  • there are ways of managing callback functions other than closures. I get the impression that your feelings about closures are due to a lack of understanding of how they work. – zzzzBov Jun 10 '11 at 18:09
  • 1
    @zzzzBov I understand how they work, and yes I've done various things for callbacks within my own apis to clean them up, but for setting up for instance a DOM onclick, you are pretty much forced to use a closure if you want to avoid global variables or strings to pass in information. – rob Jun 10 '11 at 21:05
  • I don't see how closures make for hard to read code, or why they are hard to understand. The scope of a closure is very clear: it's (lexically) bound to the scope in which it was defined. Weird bugs come about due to bad code or with closures not being used properly (due to a lack of understanding of how they work). – Vivin Paliath Jun 10 '11 at 21:43
  • 1
    Well, I've taught javascript, and people get confused. Sure it is due to lack of understanding, but even though you and I may understand them, it is an exceptionally difficult concept for beginners. For example: http://stackoverflow.com/questions/3273210/javascript-closures-variable-scope-question (and note that mozilla even has a proprietary "let" keyword to help out here....ick!) – rob Jun 10 '11 at 22:06
1

As we know, the variables that are defined in functions, have local scope. We can't access them from outside of the function.

Problem 1:

local variables are created when the function is called and they will be destroyed when the function's task is finished. It means local variables have shorter life time than global variables. We may use global variables to overcome that issue.

Global variables are available when the program starts and are destroyed when it ends. They are also available throughout the program.

Problem 2:

Since global variables are accessible throughout the program, they are prone to change from everywhere.

What do we want?

We want to have data persistency + data encapsulation.

We can achieve them by using Closures. By using a closure we can have private variables that are available even after a function's task is finished.

Example:

function initCounter() {
  let counter = 0;

  return function () {
    return ++counter;
  }
}

// Each counter is persistent
const countJumps = initCounter();
countJumps();
countJumps();
alert("Jumps count is: " + countJumps());

const countClicks = initCounter();
countClicks();
countClicks();
countClicks();
countClicks();
alert("Clicks count is: " + countClicks());


// Each counter is isolated
alert(counter); // Error: counter is not defined
AliN11
  • 2,387
  • 1
  • 25
  • 40