Closure
In this post I'm going to be taking a look at the idea of closure and how it can be used in JavaScript. Closure can seem almost mystical at first glance and can certainly be a mind bender.
Scope
Before diving any deeper into closure let's first wrestle with the idea of scope....
You can play with code from the above image here.
The variable names are fairly self explanatory, but as you can see the inner functions have access to any variables declared in the function they are nested inside, but the outer functions can not access any variables declared inside the functions that are nested within them. This is important.
Moving on..
Closure is often leveraged in JavaScript to make modules, in order stop variables interacting with each other and causing unexpected side effects. Closures make code more compact, readable and beautiful and promote functional re-use. Understanding closure will greatly improve your ability to write clean and reusable code in JavaScript.
So lets begin to try and wrap our heads around the concept. The first step to understanding closure is to understand that a reference to function can be returned to a variable, what's that supposed to mean? ..let's look at a quick example.
You can play with code from the above image here.
In this case that variable is hi
, it can then be invoked and the returned function that it stores will run.
How does this differ from other languages?
A programmer using Java would think of the function as returning a pointer to a function, and that the variables speak
and hi
were each a pointer to a function.
There is a key difference between a Java pointer to a function and a JavaScript reference to a function. In JavaScript, you can think of a function reference variable as having both a pointer to a function as well as a hidden pointer to a closure.
This means that the inner function has access to the outer functions variables, and therefore has three scope chains: it has access to its own scope (variables defined between its curly brackets), it has access to the outer function’s variables, and it has access to the global variables ( although it is probably best to avoid global variables all together )..
This may sound weird, but I think of the outer function as almost blossoming the inner function which is still attached to outer leaves as it blossoms like this...
In fairness I did give you a weirdness warning.Regardless, In most other common languages, after a function returns, all the local variables are no longer accessible because the stack-frame is destroyed.
The above code has a closure because the anonymous function function() { log(
is declared inside another function, Hi ${name}
); }hello()
. In JavaScript, if you use the function keyword inside another function, you are creating a closure.
This is an extremely powerful idea, and allows us to expose aspects of our code whilst simulating privacy, let's look at a more interesting example.
You can play with code from the above image here.
As always the code is commented to hopefully highlight what is going on, this is a simple example of how to expose a public api ( the things a user or program can interact with ), using a module pattern ( and closure ) in JavaScript.
Some additional resources:
Thanks for reading and happy coding!
Great explanation @harps116, I enjoyed reading it! Maybe you could add a section about IFEEs? It's a great way of organizing code into modules by using closures. Keep up the great work!
Thanks @petarjs I think I'll cover IFEEs another time, keep up the good work you have some great posts!
Thank you very much! And so do you! I'd love to see a strong JavaScript community on Steemit. We can help create it :)
A strong JavaScript community would be great to see, I know @matthewdavid and @fluidbyte would also like to see the js community grow.
Thanks for the post. Closures can be confusing. But this line that I saw somewhere else helped demystify them form me...
Closures take a snapshot of the function's local scope and make it available to be used in an outside scope .
I couldn't find that exact line, but to be clear inner functions take a snapshot of an outer functions variables that can then be used in the inner function even if the outer function has returned. Glad the post helped.
I meant on a different site.
Congratulations @harps116! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
Congratulations @harps116! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
You got your First payout
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP
As I've been learning JS over the last couple years, one big challenge was having a foot in the ES5 patterns around closures (modules, IIFEs) versus ES6 patterns that change the approach (imports, arrow functions, let) vs Node (require).
Having waded through it all, I think knowing all of the ways to tackle it is valuable -- especially when so much legacy code uses patters from ES5 and earlier. That the browsers still haven't fully implemented the ES6 import spec (though I heard as of Chrome 60 it was available as en experimental option).