Javascript 101: Closures
It's a topic that has ambushed Newbie devs from time immemorial. Most consider it a separation technique to distinguish the strong from the weak, the mature from the frail, the…. Ok enough with the hype. What are closures?
A Closure is a feature that allows a function reference variable bindings from the lexical scope surrounding it at author time; irrespective of where the function is invoked.
If that made no sense(as I suspect it didn’t), Here’s why; To understand closures one needs to be familiar with the concept of lexical scoping and variable binding. Let's go deeper.
What is a Scope
A scope is a set of rules that determine where and how a variable(identifier) can be looked up and found either in its current or any nested scope it’s contained within
Above there are three scopes in play. The First scope(green) has the function Identifier named foo, the second(yellow) has the identifiers; a, b and bar while the last(blue) has c. Lexical scoping grants nested scopes the ability to reference variables within parent scopes, like what we see in scope 3 where variables a and b though declared within scope 2 are used alongside variable c in the log method of the console object — console.log(a,b,c).
If a variable cannot be found in an initial enclosing scope(i.e scope 3), the Javascript engine consults the next surrounding scope(i.e scope 2) till its found or the global scope(i.e scope 1) is reached. Capiche?
Variable binding
Variable binding is when the compiler assigns a variable to a specific scope — where that variable will be available for use
Bindings created for function parameters or declared inside a function can be referenced only in that function and its child scopes via lexical scoping, so they are known as local bindings. For example, variable b is a local binding that would be assigned to scope 2 at compile time.
Understanding Closures
The feature that allows a function reference variable bindings from the lexical scope around it, irrespective of where it is invoked is called a closure.
The function bar is an example of closure here. It not only has a local binding but also from within(scope 3) references identifiers present in the lexical scope surrounding it(scope 2 in this case).
I must mention that closures find practical relevance in the fact that they can remember and access their lexical scope even when invoked outside of it; This does not mean the function bar is less of a closure, but just doesn't communicate the full power of what a closure can do. We need to let the beast(closure) out of its cage(function foo). 😆
Module pattern: A Practical approach to Closures
Closures are used by the module pattern (a design principle in Javascript that aids in writing cleaner code) to achieve the encapsulation of private state(An uncommon trait in Javascript).
Above is a simple implementation of the module pattern where function foo returns the closure bar during its invocation. The variable b is an example of an encapsulated state because it cannot be redefined and is available to the function MyFunc even after function foo had run its course.
Conclusion
Woo!! That was a lot to digest. If you didn't nod off during your read then you should be confident enough to explain Closures to any inquirer. For further study, please do consult this material. Thanks for staying tuned 👋
Next stop — What is This
References
You Don’t Know JS: Scope & Closures — https://www.amazon.ca/You-Dont-Know-JS-Closures/dp/1449335586