JavaScript closures for beginners
Submitted by Morris on Tue, 2006-02-21 10:19. Community-edited since.
Closures are not magic
This page explains closures so that a programmer can understand them — using working JavaScript code. It is not for gurus or functional programmers.
Closures are not hard to understand once the core concept is grokked. However, they are impossible to understand by reading any theoretical or academically oriented explanations!
This article is intended for programmers with some programming experience in a mainstream language, and who can read the following JavaScript function:
function sayHello(name) {
var text = 'Hello ' + name;
var say = function() { console.log(text); }
say();
}
sayHello('Joe');
How do JavaScript closures work?, A closure is a pairing of: A function, and; A reference to that function's outer scope (lexical environment). A lexical environment is part of every execution context A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.
Whenever you see the function keyword within another function, the inner function has access to variables in the outer function.
function foo(x) {
var tmp = 3;
function bar(y) {
console.log(x + y + (++tmp)); // will log 16
}
bar(10);
}
foo(2);
Closures, In JavaScript, closures are created every time a function is created, at function At first glance, it might seem unintuitive that this code still works. you might expect that the name variable would no longer be accessible. The variable add is assigned the return value of a self-invoking function. This is called a JavaScript closure. It makes it possible for a function to have " private " variables. A closure is a function having access to the parent scope, even after the parent function has closed.
FOREWORD: this answer was written when the question was:
Like the old Albert said : "If you can't explain it to a six-year old, you really don't understand it yourself.". Well I tried to explain JS closures to a 27 years old friend and completely failed.
Can anybody consider that I am 6 and strangely interested in that subject ?
I'm pretty sure I was one of the only people that attempted to take the initial question literally. Since then, the question has mutated several times, so my answer may now seem incredibly silly & out of place. Hopefully the general idea of the story remains fun for some.
I'm a big fan of analogy and metaphor when explaining difficult concepts, so let me try my hand with a story.
Once upon a time:
There was a princess...
function princess() {
She lived in a wonderful world full of adventures. She met her Prince Charming, rode around her world on a unicorn, battled dragons, encountered talking animals, and many other fantastical things.
var adventures = [];
function princeCharming() { /* ... */ }
var unicorn = { /* ... */ },
dragons = [ /* ... */ ],
squirrel = "Hello!";
/* ... */
But she would always have to return back to her dull world of chores and grown-ups.
return {
And she would often tell them of her latest amazing adventure as a princess.
story: function() {
return adventures[adventures.length - 1];
}
};
}
But all they would see is a little girl...
var littleGirl = princess();
...telling stories about magic and fantasy.
littleGirl.story();
And even though the grown-ups knew of real princesses, they would never believe in the unicorns or dragons because they could never see them. The grown-ups said that they only existed inside the little girl's imagination.
But we know the real truth; that the little girl with the princess inside...
...is really a princess with a little girl inside.
How do JavaScript closures work under the hood [Dmitry Frank], JavaScript Closures Global variables can be made local (private) with closures. You could use a global variable, and a function to increase the counter: It did not work because we display the global counter instead of the local counter. Closure Within a Loop . Introduction to Closures in JavaScript. A closure is a combination of a function bundled together with references to its surrounding state i.e. the lexical environment. In other words, a closure provides you access from an inner function to an outer function’s scope. Most of the Developers use closures in JavaScript consciously or unconsciously.
Taking the question seriously, we should find out what a typical 6-year-old is capable of cognitively, though admittedly, one who is interested in JavaScript is not so typical.
On Childhood Development: 5 to 7 Years it says:
Your child will be able to follow two-step directions. For example, if you say to your child, "Go to the kitchen and get me a trash bag" they will be able to remember that direction.
We can use this example to explain closures, as follows:
The kitchen is a closure that has a local variable, called trashBags
. There is a function inside the kitchen called getTrashBag
that gets one trash bag and returns it.
We can code this in JavaScript like this:
function makeKitchen() {
var trashBags = ['A', 'B', 'C']; // only 3 at first
return {
getTrashBag: function() {
return trashBags.pop();
}
};
}
var kitchen = makeKitchen();
console.log(kitchen.getTrashBag()); // returns trash bag C
console.log(kitchen.getTrashBag()); // returns trash bag B
console.log(kitchen.getTrashBag()); // returns trash bag A
JavaScript Function Closures, Learn How Closures Work in JavaScript: A Hands-on guide fundamental concept of JavaScript that every JavaScript developer should know In JavaScript, closure is the grouping of a function and where that function declared. In JavaScript, all functions work like closures. A closure is a function uses the scope in which it was declared when invoked. It is not the scope in which it was invoked.
The Straw Man
I need to know how many times a button has been clicked and do something on every third click...
Fairly Obvious Solution
// Declare counter outside event handler's scope
var counter = 0;
var element = document.getElementById('button');
element.addEventListener("click", function() {
// Increment outside counter
counter++;
if (counter === 3) {
// Do something every third time
console.log("Third time's the charm!");
// Reset counter
counter = 0;
}
});
<button id="button">Click Me!</button>
Understanding Closures in JavaScript, A gentle introduction to the topic of closures, key to understanding how JavaScript functions work. If you’ve ever written a function in JavaScript, you already made use of closures. It’s a key topic to understand, which has implications on the things you can do. When a function is run, it’s executed with the scope that was in place when it was defined, and not with the state that’s in place when it is executed.
How do JavaScript closures work?, Closures are one of the key concepts of JavaScript and allow developers to write better Of course, the outer function does not have access to the inner scope. Alright, now that we clarified how closures work, it's time to see them in action. - Since all JavaScript functions are closures, it's obvious: when you define a function, you actually define a closure. So, it is created when the function is defined. But make sure you distinguish between closure creation and new scope object creation: the closure (function + reference to the current scope chain)
Closures in Javascript for beginners, Even if they do unconsciously it works fine in most of the cases. But knowing closure will provide better control over the code when using them. And another reason Closures are an extremely powerful property of JavaScript (and most programming languages). As defined on MDN : Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure ‘remembers’ the environment in which it was created.
Closure in JavaScript, You should be familiar with JavaScript variable scope before you read further, Closures store references to the outer function's variables; they do not store This type of index referencing works with any type of nested array: Then, whenever a closure is created, a reference to the object that stores all of the local context variables is stored with the closure. When all referencing closures are gone, the garbage collector can clean up that variable context object; but as long as the closure is accessible, it keeps access to the variables from the enclosing environment where it was created.
Comments My problem with these and many answers is that they approach it from an abstract, theoretical perspective, rather than starting with explaining simply why closures are necessary in Javascript and the practical situations in which you use them. You end up with a tl;dr article that you have to slog through, all the time thinking, "but, why?". I would simply start with: closures are a neat way of dealing with the following two realities of JavaScript: a. scope is at the function level, not the block level and, b. much of what you do in practice in JavaScript is asynchronous/event driven. @Redsandro For one, it makes event-driven code a lot easier to write. I might fire a function when the page loads to determine specifics about the HTML or available features. I can define and set a handler in that function and have all that context info available every time the handler is called without having to re-query it. Solve the problem once, re-use on every page where that handler is needed with reduced overhead on handler re-invocation. You ever see the same data get re-mapped twice in a language that doesn't have them? Closures make it a lot easier to avoid that sort of thing. For Java programmers, the short answer is that it's the function equivalent of an inner class. An inner class also holds an implicit pointer to an instance of the outer class, and is used for much the same purpose (that is, creating event handlers). Understood this much better from here: javascriptissexy.com/understand-javascript-closures-with-ease . Still needed a closure on closure after reading the other answers. :) I found this practical example to be very useful: youtube.com/watch?v=w1s9PgtEoJs This sounds nice: "A closure in JavaScript is like keeping a copy of the all the local variables, just as they were when a function exited." But it is misleading for a couple reasons. (1) The function call does not have to exit in order to create a closure. (2) It is not a copy of the values of the local variables but the variables themselves. (3) It doesn't say who has access to these variables. Example 5 shows a "gotcha" where the code doesn't work as intended. But it doesn't show how to fix it. This other answer shows a way to do it. I like how this post starts off with big bold letters saying "Closures Are Not Magic" and ends its first example with "The magic is that in JavaScript a function reference also has a secret reference to the closure it was created in". Example #3 is mixing closures with javascripts hoisting. Now I think explaining only closures is difficult enough without bringing in the hoisting behaviour. This helped me the most: Closures are functions that refer to independent (free) variables. In other words, the function defined in the closure 'remembers' the environment in which it was created.
from developer.mozilla.org/en-US/docs/Web/JavaScript/Closures ECMAScript 6 may change something in this great article about closure. For example, if you use let i = 0
instead of var i = 0
in Example 5, then the testList()
will print what you want originally. @feeela: Yes, every JS function creates a closure. Variables that are not referenced will likely be made eligible for garbage collection in modern JS engines, but it doesn't change the fact that when you create an execution context, that context has a reference to the enclosing execution context, and its variables, and that function is an object that has potential to be relocated to a different variable scope, while retaining that original reference. That's the closure.