JavaScript closures were always hard to understand because of the way they are explained. The closure is one of the most important core concepts of JavaScript.
“Writing in ECMAScript language without understanding closure is like writing Java without understanding classes” — Douglas Crockford, father of JSON
In most of the examples, you will see people explaining this as a function inside another function but in reality, it is much more than this.
Take a look at the code below:
var x = 0;
addNumber = () => {
return 5 + x;
}
console.log(addNumber);
JavaScript is a lexical scoping language, the inheritance flows inwards. The above code uses a global scope and there is nothing to protect it against change. A variable declared outside the function is available for use within the function. You can not use a variable outside that's been declared inside a function.
Now let me introduce you to closure. Look at the below code.
closedFunction = () => {
var counter = 0;
var increment = () => {
counter++;
console.log(counter);
}
return { increment }
}
var countMe = closedFunction();
console.log(countMe.increment()); //returns 1
console.log(countMe.increment()); //returns 2
The scope of the function is created once and memory gets allocated for it. Processing happens until it reaches the end of the function and the memory gets released. There is no permanence gained in the exercise and whatever value created is forever lost.
However, if you wrap your function within a function, it creates another scope — a sort of ring fence around your code that tells JavaScript not to destroy your function when it ends.
The counter variable in the code above becomes the enclosed variable because it is outside the function being called (i.e. Increment). As a result, you can create an unlimited number of function instances with its own set of unique values.
In a way, closures are just functions with preserved data. When you create a closure, you’re telling JavaScript to remember the state of things inside your function — and only the variables that are used are considered ‘closures’.
Top comments (4)
Great explanation. I find it easy to think of it this way. However I am a bit flummoxed as to why your example returns 1 the first time it is called, whereas the below code returns 0 the first time it is called:
let uniqueInteger = (function() {
let counter = 0;
return function() { return counter++; };
}());
uniqueInteger()
This is from Javascript The Definitive Guide. Good book but their section on Closures has me confused on this point.
In simple words the "Closure" means doing programming in such a way that the method remembers the variables that have been passed even after the execution of the method.
Can this create a memory leak or does it get garbage collected at some point?
See this stackoverflow answer for details of inner workings of closures.