Closures in Javascript - Time & Space Complexity
We want to see how the time it takes to run code with closures changes as the input grows.
How does using closures affect the number of steps the program does?
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 function using a closure and calls it n times to increase the count.
- Primary operation: Calling the inner function that increments the count.
- How many times: The loop calls this function n times.
Each call to the counter function does a simple addition and returns a value.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 increments |
| 100 | 100 increments |
| 1000 | 1000 increments |
Pattern observation: The number of steps grows directly with n, so doubling n doubles the work.
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 make code slower because they add extra layers."
[OK] Correct: The closure itself just keeps data safe; calling the inner function still takes constant time each call, so time grows normally with input size.
Understanding how closures affect time helps you explain your code clearly and shows you know how functions work under the hood.
"What if the inner function called itself recursively inside the closure? How would the time complexity change?"
Practice
Solution
Step 1: Understand closure definition
A closure is a function that keeps access to variables from the place where it was created, even after that place has finished running.Step 2: Match definition to options
A function that remembers variables from its creation context correctly describes this behavior, while others describe unrelated concepts.Final Answer:
A function that remembers variables from its creation context -> Option DQuick Check:
Closure = function remembering variables [OK]
- Thinking closures are functions without parameters
- Confusing closures with immediately invoked functions
- Believing closures only run once
Solution
Step 1: Identify closure syntax
A closure requires an inner function that accesses variables from the outer function and is returned so it can be used later.Step 2: Check options for correct closure
function outer() { let x = 5; return function inner() { return x; } } returns an inner function that uses outer variable x, forming a closure. Others either don't return the function or don't access outer variables correctly.Final Answer:
function outer() { let x = 5; return function inner() { return x; } } -> Option CQuick Check:
Return inner function accessing outer variable [OK]
- Not returning the inner function
- Returning only the variable, not a function
- Defining inner function but not using outer variables
function makeCounter() {
let count = 0;
return function() {
count += 1;
return count;
};
}
const counter = makeCounter();
console.log(counter());
console.log(counter());Solution
Step 1: Understand closure behavior in makeCounter
The inner function increments count and returns it. The variable count is remembered by the closure.Step 2: Trace the calls to counter()
First call: count = 0 + 1 = 1, returns 1. Second call: count = 1 + 1 = 2, returns 2.Final Answer:
1 and 2 -> Option AQuick Check:
Closure keeps count incrementing: 1, 2 [OK]
- Thinking count resets each call
- Expecting output 1 and 1
- Confusing closure with global variable
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]());
console.log(functions[1]());Solution
Step 1: Identify loop variable scope
The loop uses var i, which is function-scoped, so all inner functions share the same i.Step 2: Understand closure captures final i value
After loop ends, i is 3. All functions return 3, not 0, 1, 2 as expected.Final Answer:
All functions return 3 instead of 0, 1, 2 -> Option AQuick Check:
var in loop causes shared i = 3 [OK]
- Assuming each function captures separate i
- Thinking semicolons cause error
- Expecting ReferenceError or undefined
i? function createFuncs() {
let funcs = [];
for (var i = 0; i < 3; i++) {
funcs.push(function() { return i; });
}
return funcs;
}Solution
Step 1: Understand block scope with let
Using let in the for loop creates a new binding of i for each iteration, so closures capture different i values.Step 2: Compare with var behavior
var is function-scoped, so all closures share the same i. Changing to let fixes this by giving each iteration its own i.Final Answer:
Changevartoletin the for loop declaration -> Option BQuick Check:
let in loop creates separate i per iteration [OK]
- Trying to fix by making i global
- Returning i instead of function
- Using var with immediate call but misunderstanding closures
Ready to prove it?
Pass the test and this pattern moves unknown
