Practical closure use cases in Javascript - Time & Space Complexity
We want to see how the time it takes to run code with closures changes as we use them in different ways.
How does the use of closures affect the number of steps the program takes?
Analyze the time complexity of the following code snippet.
function makeCounter() {
let count = 0;
return function() {
count += 1;
return count;
};
}
const counter = makeCounter();
for (let i = 0; i < n; i++) {
counter();
}
This code creates a counter using a closure and calls it n times to increase the count.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Calling the inner function that increments the count.
- How many times: The inner function runs once for each loop iteration, so n times.
Each time we call the counter function, it does a simple addition and returns a value.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 simple increments |
| 100 | 100 simple increments |
| 1000 | 1000 simple increments |
Pattern observation: The number of operations grows directly with n, increasing steadily.
Time Complexity: O(n)
This means the time to run grows in a straight line with the number of times we call the closure.
[X] Wrong: "Closures always slow down code a lot because they keep data inside."
[OK] Correct: The closure itself just holds data, but calling the function inside the loop still takes one step per call, so the time grows linearly, not worse.
Understanding how closures work with loops helps you explain how your code handles repeated actions and data storage, a useful skill in many coding tasks.
"What if the inner function called inside the loop also contained another loop running m times? How would the time complexity change?"
Practice
Solution
Step 1: Understand closure concept
Closures let a function remember variables from the place where it was created, even after that place has finished running.Step 2: Compare options
Only They allow functions to remember variables from their creation context. correctly describes this key feature. Other options describe unrelated or incorrect ideas.Final Answer:
They allow functions to remember variables from their creation context. -> Option BQuick Check:
Closure = Remember variables [OK]
- Thinking closures speed up code automatically
- Confusing closures with garbage collection
- Believing closures remove the need for functions
Solution
Step 1: Identify closure pattern
function counter() { let count = 0; return function() { count++; return count; }; } defines a function that returns another function which accesses the variable 'count' inside its scope, creating a closure.Step 2: Check other options
function counter() { var count = 0; count++; return count; } increments count but does not return a function, so no closure. let count = 0; function counter() { count++; return count; } uses a global variable, not private. function counter() { return count++; let count = 0; } has syntax error (return before variable declaration).Final Answer:
function counter() { let count = 0; return function() { count++; return count; }; } -> Option DQuick Check:
Closure = function inside function with private variable [OK]
- Returning value instead of function for closure
- Using global variables instead of private ones
- Placing return before variable declaration
function makeAdder(x) {
return function(y) {
return x + y;
};
}
const add5 = makeAdder(5);
console.log(add5(3));Solution
Step 1: Understand makeAdder function
makeAdder returns a function that adds its argument y to x, which is remembered via closure.Step 2: Calculate add5(3)
add5 is makeAdder(5), so x=5. Calling add5(3) returns 5 + 3 = 8.Final Answer:
8 -> Option CQuick Check:
Closure adds remembered x to y = 8 [OK]
- Concatenating numbers as strings
- Forgetting closure remembers x
- Expecting undefined or NaN
function createFuncs() {
let funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(function() { return i; });
}
return funcs;
}
const functions = createFuncs();
console.log(functions[0]());Solution
Step 1: Analyze loop variable scope
Using var for i means one shared variable. All functions capture the same i, which after loop ends is 3.Step 2: Understand closure effect
Each function returns i, but i is 3 at call time, so all return 3, not 0,1,2.Final Answer:
All functions return 3 instead of 0, 1, 2 due to var scoping. -> Option AQuick Check:
var in loop causes shared i = 3 [OK]
- Assuming each function captures separate i
- Thinking semicolons cause error
- Expecting functions array to be empty
function createFuncs() {
let funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(function() { return i; });
}
return funcs;
}
const functions = createFuncs();
console.log(functions[0](), functions[1](), functions[2]());Solution
Step 1: Understand problem with var
var is function-scoped, so all functions share same i, which ends at 3.Step 2: Fix with let for block scope
Replacing var with let makes i block-scoped, so each iteration has its own i captured by closure.Final Answer:
Replace var with let in the for loop declaration. -> Option AQuick Check:
let creates separate i per loop iteration [OK]
- Using global variables causing shared state
- Thinking IIFE is only solution
- Believing code works without changes
Ready to prove it?
Pass the test and this pattern moves unknown
