A closer look to closure
Written by Kevin Gimbel on 20.07.2014, 🍿 4 min. read
Closure is a very interesting concept in JavaScript. It basically determinse where and how variables or functions are accessable and where not. Since this is an essential part of JavaScript and one can run into quite some problems I want to try and give short introduction to closure and what it can be good for. It's good to have at least basic understanding of JavaScript.
So before I start I'd like to say that I consider myself a JavaScript beginner and this is how I understand closure and scopes at the moment. If you happen to find mistakes please tweet me or open an issue.
Consider the following example
var x = 5;
(function(){
var x = 10;
}());
console.log(x);
What value will x
have when logged to the console? 5 or 10? The correct answer is 5, because inside the immediate
executing function var x
does not reference the previously defined var x
. They're both standalone and do not effect
each other. Let's try this again and see what happens now
var x = 5;
(function() {
x = 10;
}());
console.log(x);
What value will x
have now? Still 5, because it's the same function but we only left the var
keyword? Nope, now x
inside the immediate executing function references the previously defined var x
and will update it's value, so
console.log(x)
results to 10 this time. As you can see just now, leaving out the single word var
can change how your
program behaves. The missing var statment, where closure hits hard and overrides the variable, can really be annoying
because JavaScript doesn't throw errors. Overriding values inside a closure, e.g. the immediate executing function, is
perfectly fine.
So what happens if we pass x
, which is 10 now, to the immediate executing function and declare 'x = 15' inside the
functions body? Will x
become 15 or stay 10?
// x is 10 at this point
(function(x){
x = 15;
}(x));
As the result shows, x is still 10. But wait, wasn't it supposed to be overridden if we don't declare var x = 15
? Well
that is true, but since we pass x as a parameter, x is "re-defined" as a local variable and, inside the functions body, it is
indeed 15 - outside it is not.
See the Pen nwmCD by Kevin Gimbel (@kevingimbel) on CodePen.
What can closures do for me?
What can it do? Good stuff. Closures can help to organize code and keep the global namespace clear. In general one shouldn't write variables into the global namespace because they're almost asking to be overriden or changed. Let's say one writes a function like this.
var assert = function(con, msg) {
if(!con) {
console.error(msg);
} else {
console.log(msg);
}
}
That's a super simple assert function to see if a statment (con
dition) is true or false. If it's false we'll log a console.error(), if not we'll log a normal console.log() statement. This is great and perfectly fine unless someone else
tries to use a function with the same name. Then there'll be a "conflict" and the last declared function overrides the other. (In this example I'll use a function called myFunction)
See the Pen wuAdv by Kevin Gimbel (@kevingimbel) on CodePen.
So still, what can closure do for me? It can save my declared functions - inside a closure. So far all closure examples were immediate executing function, but Objects also create closures, assigning all there properties to a specific "namespace".
var myFunction() = function() {
return true;
}
var myNamespace = {
myFunction: function() {
return false;
}
}
This way we introduce one variable to the global scope: myNamespace and keep all the functions inside this scope. Therefore, the myFunction() is still accessable within the scope and has the expected results, no matter who declares myFunction in the globale scope.
See the Pen ELfal by Kevin Gimbel (@kevingimbel) on CodePen.