Elevating JavaScript with Closures: A Journey into Scopes, Data Encapsulation, and More!
Exercise 1: Basic Closure
Problem: Create a function createGreeting that takes a greeting message, returns another function that takes a name and then combines them.
Explanation: Demonstrates how closures allow a function to access outer function scopes.
Code:
function createGreeting(greeting) {
?return function(name) {
?console.log(`${greeting}, ${name}!`);
?};
}
const greetHello = createGreeting("Hello");
greetHello("Alice"); // Outputs: Hello, Alice!
Exercise 2: Counter Closure
Problem: Create a function createCounter that allows you to increment and return a counter value.
Explanation: Shows how closures can encapsulate data, creating private state.
Code:
function createCounter() {
?let count = 0;
?return function() {
?count++;
?return count;
?};
}
const counter = createCounter();
console.log(counter()); // Outputs: 1
console.log(counter()); // Outputs: 2
Exercise 3: Creating Private Variables
Problem: Create a function person that takes a name and returns an object with methods to get and set that name, without allowing direct access to the name itself from outside.
Explanation: Utilizes closures to create private variables.
Code:
function person(initialName) {
?let name = initialName;
?return {
?getName: function() {
?return name;
?},
?setName: function(newName) {
?name = newName;
?}
?};
}
const p = person("Alice");
console.log(p.getName()); // Outputs: Alice
p.setName("Bob");
console.log(p.getName()); // Outputs: Bob
Exercise 4: Function Factories
Problem: Create a function makeMultiplier that takes one number and returns a function that multiplies any number by the first number.
Explanation: Demonstrates how function factories use closures to remember and use variables from their scope.
Code:
function makeMultiplier(x) {
?return function(y) {
?return x * y;
?};
}
const double = makeMultiplier(2);
console.log(double(3)); // Outputs: 6
Exercise 5: Encapsulating Function Logic
Problem: Write a closure that encapsulates and modifies an array without exposing the array to the global scope.
Explanation: Teaches data encapsulation and protection using closures.
Code:
function arrayManager() {
?let arr = [];
?return {
?addItem: function(item) {
?arr.push(item);
?},
?getItem: function(index) {
?return arr[index];
领英推荐
?}
?};
}
const manager = arrayManager();
manager.addItem("Apple");
console.log(manager.getItem(0)); // Outputs: Apple
Exercise 6: Closures in Loops
Problem: Fix the following code so that each function in the array functions alerts its corresponding index.
Explanation: Shows common closure-in-loop problem and how to solve it with closures.
Code:
let functions = [];
for (var i = 0; i < 3; i++) {
?functions[i] = (function(index) {
?return function() {
?console.log(index);
?};
?})(i);
}
functions[0](); // Should output: 0
functions[1](); // Should output: 1
functions[2](); // Should output: 2
Exercise 7: Timing with Closures
Problem: Create a function delayedLogger that takes a message and a delay time, then prints that message to the console after the delay.
Explanation: Utilizes closures to "remember" both the message and the delay when the timeout completes.
Code:
function delayedLogger(message, delay) {
?setTimeout(function() {
?console.log(message);
?}, delay);
}
delayedLogger("Hello after 3 seconds", 3000);
Exercise 8: Closure Scope Chain
Problem: Create a function outer that defines a variable x and returns an inner function. The inner function should define its variable y and return a function that accesses both x and y.
Explanation: Demonstrates how closures have access to the outer function’s scope chain.
Code:
function outer() {
?let x = 'x';
?return function() {
?let y = 'y';
?return function() {
?console.log(x, y); // Access both x and y
?};
?};
}
const inner = outer()();
inner(); // Outputs: x y
Exercise 9: Modularize Functions
Problem: Using closures, create a module mathOperations that has functions for addition and subtraction.
Explanation: Shows how to create modules using closures for encapsulating functionalities.
Code:
function mathOperations() {
?return {
?add: function(a, b) {
?return a + b;
?},
?subtract: function(a, b) {
?return a - b;
?}
?};
}
const operations = mathOperations();
console.log(operations.add(5, 3)); // Outputs: 8
console.log(operations.subtract(5, 3)); // Outputs: 2
Exercise 10: Memory Efficiency
Problem: Discuss how using closures can lead to more memory-efficient code by creating a closure that encloses large data structures and provides a method to query them.
Explanation: Explores how closures can encapsulate large datasets, preventing them from polluting the global namespace and maintaining them in memory only as long as necessary.
Code: Not applicable for a discussion problem, but encourage understanding the concept of encapsulating data within a closure to prevent global scope pollution and keep memory usage efficient.