What is Closure?
In JavaScript, closure is a combination of a function and the lexical environment within which that function was declared. You may think what is a lexical environment? It is an environment that is wrapped with curly brackets.
function lexical() {
// This is the lexical environment
}
In simpler terms, a closure allows a function to access variables from its outer function.
Example
function test() {
const a = "a";
console.log(
"test:",
typeof a !== "undefined" ? "a" : new Error("Variable 'a' does not exist in test"),
);
console.log(
"test:",
typeof b !== "undefined" ? "b" : new Error("Variable 'b' does not exist in test"),
);
console.log(
"test:",
typeof c !== "undefined" ? "c" : new Error("Variable 'c' does not exist in test"),
);
return function test2() {
const b = "b";
console.log(
"test2:",
typeof a !== "undefined" ? a : new Error("Variable 'a' does not exist in test2"),
);
console.log(
"test2:",
typeof b !== "undefined" ? b : new Error("Variable 'b' does not exist in test2"),
);
console.log(
"test2:",
typeof c !== "undefined" ? c : new Error("Variable 'c' does not exist in test2"),
);
return function test3() {
const c = "c";
console.log(
"test3:",
typeof a !== "undefined" ? a : new Error("Variable 'a' does not exist in test3"),
);
console.log(
"test3:",
typeof b !== "undefined" ? b : new Error("Variable 'b' does not exist in test3"),
);
console.log(
"test3:",
typeof c !== "undefined" ? c : new Error("Variable 'c' does not exist in test3"),
);
};
};
}
test()()();
// test: a
// test: Error: Variable 'b' does not exist in test
// test: Error: Variable 'c' does not exist in test
// test2: a
// test2: b
// test2: Error: Variable 'c' does not exist in test2
// test3: a
// test3: b
// test3: c
Each nested functions form a closure. When a closure is created, it maintains a reference to the variables in its outer function, even if the outer function has finished executing. For example, the test2
function has access to the a
variable from the outer scope of the test
function. This is because the closure formed by the test2
retains a reference to the variables in the scope of its parent function, the test
function. Similar idea for the test3
function.
Closures allow the inner functions to access the variables they need from the outer scopes, even when those variables are not directly passed as arguments. This can be a powerful mechanism in JavaScript for encapsulating data and creating private variables or functions.
Recap
Initially, understanding the concept of closure might seem challenging. However, once you observe the pattern, it becomes quite straightforward. An important characteristic of closure is that an outer function cannot access its own inner function(s), while an inner function can access its own outer function(s). For instance, the test3
function access variables a
and b
from its outer functions, which are the test
and test2
functions. On the other hand, the test
function cannot access variables b
and c
from its inner functions, which are the test2
and test3
functions.
I hope the provided example helps to illustrate this concept effectively!
Resources
Thank you!
Thank you for your time and for reading this!