Closures Explained
Key Concepts
- What is a Closure?
- Lexical Scope
- Creating a Closure
- Practical Uses of Closures
- Common Pitfalls
What is a Closure?
A closure is a function that has access to its own scope, the scope in which it was created, and the global scope. Closures are created every time a function is created, at function creation time.
Lexical Scope
Lexical scope refers to the scope that is defined at the time of writing the code. A function's lexical scope is the scope in which the function was defined. Closures have access to variables in their lexical scope, even after the outer function has returned.
Creating a Closure
A closure is created when a function is defined inside another function and the inner function references variables from the outer function's scope. The inner function retains access to these variables even after the outer function has finished executing.
Example:
function outerFunction() { let outerVariable = "I am outside!"; function innerFunction() { console.log(outerVariable); } return innerFunction; } let closure = outerFunction(); closure(); // Outputs: "I am outside!"
Practical Uses of Closures
Closures are useful for creating private variables, encapsulating logic, and implementing data hiding. They can also be used to create functions that remember their state between calls.
Example: Private Counter
function createCounter() { let count = 0; return function() { count += 1; return count; }; } let counter = createCounter(); console.log(counter()); // Outputs: 1 console.log(counter()); // Outputs: 2
Common Pitfalls
One common pitfall with closures is memory leaks. Since closures keep references to their outer scope, they can prevent variables from being garbage collected, leading to memory issues. Another pitfall is unintentional variable sharing when creating multiple closures.
Example: Unintentional Sharing
function createFunctions() { let functions = []; for (let i = 0; i < 3; i++) { functions.push(function() { console.log(i); }); } return functions; } let funcs = createFunctions(); funcs[0](); // Outputs: 3 funcs[1](); // Outputs: 3 funcs[2](); // Outputs: 3