Closures
Closures are a very powerful feature in JavaScript that allow a function to access variables in its external scope, even if the external scope has already been executed by the time the function is called. Closures help us to privatize, encapsulate and modularize data, making code more concise, readable and maintainable.
Definition of closure
Simply put, a closure is a function that has the right to access variables in another function's scope.
function outerFunction() { let outerVariable = "I am outside!"; function innerFunction() { (outerVariable); // innerFunction can access outerVariable } return innerFunction; } const closure = outerFunction(); closure(); // Output: I am outside!
In the above example, theinnerFunction
is a closure that accesses theouterFunction
hit the nail on the headouterVariable
even ifouterFunction
Implementation has been completed.
Applications of closures
- Data privatization:
function createCounter() { let count = 0; return function() { count++; return count; }; } const counter = createCounter(); (counter()); // Output: 1 (counter()); // Outputs: 2 (counter()); // Outputs: 3
In this example, thecount
variables are encapsulated in thecreateCounter
within the function's scope and can only be accessed and modified by the returned closure function.
- Modeling block-level scopes:
Before ES6, JavaScript didn't have block-level scoping, and we could use closures to simulate block-level scoping.
for (var i = 1; i <= 3; i++) { (function(i) { setTimeout(function() { (i); }, i * 1000); })(i); } // Output: 1, 2, 3 (one number every second)
A new scope is created for each loop by immediately executing the function expression (IIFE), thus making thesetTimeout
hit the nail on the headi
Keep the correct value.
Event Delegation
Event Delegation is a technique that utilizes the event bubbling mechanism to add event listeners to a parent element to manage the event processing of multiple child elements. It reduces memory footprint and improves performance, and is especially useful when you need to handle a large number of dynamically generated child element events.
Event Delegate Definition
By adding an event listener to the parent element, when an event is triggered in the child element, the event will bubble up to the parent element and be handled by the parent's event listener.
<ul id="parent"> <li>Item 1</li> <li>Item 2</li> <li>Item 3</li> </ul>
('parent').addEventListener('click', function(event) { if ( === 'LI') { (); // Output the text of the clicked list item } });
In this example, we'll just add a new value for theul
element adds a click event listener, but can handle all theli
element's click event.
Application of Event Delegation
- dynamic content:
Using event delegates can simplify event handling when there are a large number of dynamically generated elements on the page.
const list = ('parent'); ('addItem').addEventListener('click', function() { const newItem = ('li'); = `Item ${ + 1}`; (newItem); });
- improve performance:
When event listeners need to be added to a large number of elements, event delegates can significantly improve performance because only one event listener needs to be added to the parent element, not to each child element.
<button id="addItem">Add Item</button> <ul id="parent"> <!-- Dynamically generated list items --> </ul>
summarize
Closures enable access to variables in external function scopes, thus enabling data privatization and encapsulation;
Event delegates utilize the event bubbling mechanism to simplify event handling and improve performance by adding event listeners to the parent element.