๐จ JavaScript ยท Topic 7 of 20
Loops โ JavaScript Questions with Answers
30 practice questions on Loops, each with the correct answer and a clear explanation of why it is right. Read through them as revision notes, or take this topic as an interactive quiz to test yourself.
3 easy ยท 18 medium ยท 9 hard ยท Part of JavaScript: The language of the web - basics to advanced, 20 topics.
Medium questions (18)
Q3. medium
What does break do inside a loop?
for (const n of nums) {
if (n > 100) break; // stop searching
console.log(n);
}
- A Exits the loop immediately
- B Skips one iteration
- C Pauses the loop
- D Restarts the loop
Answer: A โ Exits the loop immediately
break stops the loop entirely and continues after it - useful once you have found what you were searching for.
breakcontinue
Q4. medium
What does continue do?
for (let i = 0; i < 5; i++) {
if (i === 2) continue;
console.log(i); // 0 1 3 4
}
- A Skips the rest of the current iteration and moves to the next one
- B Exits the loop
- C Restarts from zero
- D Nothing
Answer: A โ Skips the rest of the current iteration and moves to the next one
continue jumps to the next iteration, skipping the remaining statements in the body for this pass only.
continuebreak
Q6. medium
What causes an INFINITE loop most often?
let i = 0;
while (i < 5) {
console.log(i);
// forgot i++ -> infinite!
}
- A Forgetting to update the variable the condition depends on
- B Using const
- C Using break
- D Nesting loops
Answer: A โ Forgetting to update the variable the condition depends on
If nothing changes the condition, it stays true forever and the browser tab freezes. Always ensure the loop makes progress toward termination.
whileDebugging
Q7. medium
What does for...of iterate over?
for (const fruit of ["apple", "mango"]) {
console.log(fruit); // apple, mango
}
- A The VALUES of an iterable (array, string, Map, Set)
- B The keys/indexes
- C Object properties
- D Only numbers
Answer: A โ The VALUES of an iterable (array, string, Map, Set)
for...of gives you each value directly - the cleanest way to loop an array when you do not need the index.
for...ofIterables
Q8. medium
What does for...in iterate over?
const user = { name: "Ana", age: 21 };
for (const key in user) {
console.log(key, user[key]);
}
- A The KEYS (property names) of an object - or indexes of an array
- B The values
- C Only arrays
- D Nothing
Answer: A โ The KEYS (property names) of an object - or indexes of an array
for...in walks enumerable property names. Use it for plain objects; for arrays prefer for...of or forEach, because for...in gives string indexes and can include inherited properties.
for...inObjects
Q10. medium
Which loop is best for iterating an array's values?
- A for...of (or forEach) - clear and index-free
- B for...in
- C do...while
- D A while loop with a counter
Answer: A โ for...of (or forEach) - clear and index-free
for...of reads naturally and avoids index bugs. Use a classic for loop when you need the index or must skip/step, and forEach when you like the callback style.
for...offorEach
Q11. medium
What is the output?
const arr = [10, 20, 30];
arr.forEach((v, i) => console.log(i, v));
- A 0 10 / 1 20 / 2 30 - the callback receives (value, index)
- B 10 0 / 20 1 / 30 2
- C Only the values
- D Error
Answer: A โ 0 10 / 1 20 / 2 30 - the callback receives (value, index)
forEach passes (value, index, array) to the callback. Note the VALUE comes first, which surprises people expecting index first.
forEachCallbacks
Q14. medium
Why does let fix the loop-closure problem?
- A let creates a NEW binding for each iteration, so every callback captures its own value
- B let is faster
- C let delays the callbacks
- D It does not fix it
Answer: A โ let creates a NEW binding for each iteration, so every callback captures its own value
The specification re-binds a let loop variable per iteration, giving each closure its own copy. var has a single shared binding for the whole function.
letClosures
Q15. medium
How do you loop BACKWARDS through an array?
- A for (let i = arr.length - 1; i >= 0; i--)
- B for (let i = arr.length; i > 0; i++)
- C for (const x of arr.reverse()) // mutates!
- D for (let i = 0; i < arr.length; i--)
Answer: A โ for (let i = arr.length - 1; i >= 0; i--)
Start at the last index (length - 1), continue while >= 0, and decrement. Option C works but reverse() MUTATES the original array - use [...arr].reverse() to avoid that.
Reverse iterationreverse()
Q16. medium
What is the output?
let sum = 0;
for (let i = 1; i <= 3; i++) sum += i;
console.log(sum);
- A 6
- B 3
- C 5
- D 0
Answer: A โ 6
1 + 2 + 3 = 6. The accumulator pattern (start at 0, add each value) is the most common loop use.
Accumulatorreduce
Q17. medium
How many times does the inner body run?
for (let i = 0; i < 3; i++)
for (let j = 0; j < 4; j++) { }
- A 12 - 3 x 4
- B 7
- C 3
- D 4
Answer: A โ 12 - 3 x 4
The inner loop runs fully for every outer iteration, so counts multiply. Nested loops are common for grids and tables - watch out for performance with large data.
Nested loopsComplexity
Q19. medium
What does this loop over?
for (const [key, value] of Object.entries(obj))
const user = { name: "Ana", age: 21 };
for (const [k, v] of Object.entries(user)) {
console.log(`${k}: ${v}`);
}
- A Each key/value pair of the object, destructured into two variables
- B Only keys
- C Only values
- D Nothing - objects are not iterable
Answer: A โ Each key/value pair of the object, destructured into two variables
Object.entries returns [key, value] arrays; destructuring in the loop header unpacks them. The modern, readable way to iterate objects (alternatives: Object.keys / Object.values).
Object.entriesDestructuring
Q20. medium
What is the output?
for (const ch of "hi") console.log(ch);
- A h then i - strings are iterable
- B hi
- C 0 1
- D Error
Answer: A โ h then i - strings are iterable
for...of works on any iterable, including strings (character by character), arrays, Maps, Sets and NodeLists.
IterablesStrings
Q23. medium
What does for (;;) do?
- A Creates an infinite loop (all three parts omitted) - needs a break inside
- B SyntaxError
- C Runs once
- D Runs zero times
Answer: A โ Creates an infinite loop (all three parts omitted) - needs a break inside
All three clauses are optional; an absent condition is treated as true. Equivalent to while (true) - use break to exit.
Infinite loopswhile(true)
Q24. medium
Which loop should you choose when you do not know how many iterations are needed?
- A while - it is condition-driven rather than count-driven
- B for - always
- C for...of
- D forEach
Answer: A โ while - it is condition-driven rather than count-driven
Use for/for...of when iterating a known collection or count; use while when looping until some state changes ('until the user quits', 'until the queue is empty').
whileChoosing loops
Q26. medium
What is the modern way to repeat something N times without needing the index?
const squares = Array.from({length: 5}, (_, i) => i * i);
// [0, 1, 4, 9, 16]
- A for (let i = 0; i < n; i++) - or Array.from({length: n}).forEach(...)
- B repeat(n)
- C times(n)
- D loop n
Answer: A โ for (let i = 0; i < n; i++) - or Array.from({length: n}).forEach(...)
JavaScript has no times() helper. A plain for loop is clearest; Array.from({length: n}, (_, i) => ...) is handy when you want to BUILD an array of n items.
Array.fromRepetition
Q28. medium
What does the map() method do compared with a for loop?
- A Builds a NEW array by transforming every element - a loop that returns a result
- B Loops without returning anything
- C Filters elements
- D Sorts the array
Answer: A โ Builds a NEW array by transforming every element - a loop that returns a result
map is a declarative loop for transformation: [1,2,3].map(n => n * 2) gives [2,4,6]. It never mutates the original. (forEach is the version that returns nothing.)
mapforEachArray methods
Q29. medium
How do you loop over a NodeList returned by querySelectorAll?
document.querySelectorAll(".item").forEach(el => el.classList.add("on"));
- A for...of or forEach - NodeLists are iterable and have forEach
- B Only a classic for loop works
- C You must convert with Array.from() first, always
- D NodeLists cannot be looped
Answer: A โ for...of or forEach - NodeLists are iterable and have forEach
Modern NodeLists support both for...of and forEach. Convert with Array.from(list) or [...list] only when you need array methods like map or filter.
DOMNodeList
Hard questions (9)
Q9. hard
What is the output?
for (const i in ["a", "b"]) console.log(typeof i);
- A "string" twice - for...in gives indexes as STRINGS
- B "number" twice
- C "a" "b"
- D undefined
Answer: A โ "string" twice - for...in gives indexes as STRINGS
Object keys are always strings, so array indexes come out as "0" and "1". This breaks arithmetic (i + 1 becomes "01") - one reason to avoid for...in on arrays.
for...inGotchas
Q12. hard
Can you break out of a forEach loop?
// early exit alternatives:
for (const x of arr) { if (x > 10) break; }
arr.some(x => x > 10); // stops at first true
- A No - break is not allowed; use for...of, some(), or every() instead
- B Yes, with break
- C Yes, with return
- D Yes, with continue
Answer: A โ No - break is not allowed; use for...of, some(), or every() instead
forEach always visits every element; break is a syntax error inside it, and return only exits the current callback (acting like continue). For early exit use for...of with break, or some()/find().
forEachsomeEarly exit
Q13. hard
What is the output?
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0); // 0 1 2
}
- A 3 3 3 - var is function-scoped, so all callbacks share one i
- B 0 1 2
- C 0 0 0
- D undefined x3
Answer: A โ 3 3 3 - var is function-scoped, so all callbacks share one i
The timeouts run after the loop finishes, when i is 3. Changing var to let creates a fresh binding per iteration and prints 0 1 2 - the classic demonstration of why let exists.
- The single most famous JavaScript interview question.
Closureslet vs varEvent loop
Q18. hard
In nested loops, what does a plain break exit?
outer:
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (j === 1) break outer; // exits BOTH
}
}
- A Only the INNERMOST loop containing it
- B All loops
- C The function
- D Nothing
Answer: A โ Only the INNERMOST loop containing it
break leaves just its own loop. To exit both, use a labelled break, a flag variable, or extract the loops into a function and return.
Labelsbreak
Q21. hard
Why is caching the length sometimes suggested?
for (let i = 0, n = arr.length; i < n; i++)
- A It avoids re-reading .length each iteration - a micro-optimisation, rarely needed today
- B It is required for correctness
- C It prevents infinite loops
- D It changes the iteration order
Answer: A โ It avoids re-reading .length each iteration - a micro-optimisation, rarely needed today
Modern engines optimise .length access, so this matters only in extreme hot loops. Readability usually wins - but it IS important if the loop modifies the array's length.
PerformanceOptimisation
Q22. hard
What is the danger of modifying an array WHILE looping over it by index?
// safest:
arr = arr.filter(x => x >= 0);
// or loop backwards when removing
- A Removing items shifts positions, so the loop can SKIP elements
- B It throws an error
- C The array becomes read-only
- D Nothing happens
Answer: A โ Removing items shifts positions, so the loop can SKIP elements
After splice(i, 1), every later element moves left while i still advances - skipping one. Loop backwards, or build a new array with filter().
splicefilterMutation
Q25. hard
What is the output?
const arr = [1, 2, 3];
for (let i = 0; i < arr.length; i++) {
if (i === 1) arr.push(99);
}
console.log(arr.length, i_ran_times = "?");
// safe: iterate a copy
for (const x of [...arr]) { arr.push(x); } // terminates
- A Length 4, and the loop runs 4 times - the condition re-reads the GROWN length each pass
- B Length 4, but the loop still runs only 3 times
- C Length 3 - push inside a loop is ignored
- D Infinite loop
Answer: A โ Length 4, and the loop runs 4 times - the condition re-reads the GROWN length each pass
i < arr.length is re-evaluated every iteration. At i=1 the push makes length 4, so the loop continues to i=3 and runs four times instead of three. Pushing on every pass would loop forever - which is why mutating an array while looping over it is dangerous.
MutationTracingInfinite loops
Q27. hard
What is the output?
let i = 0;
while (i < 3) {
i++;
if (i === 2) continue;
console.log(i);
}
- A 1 then 3
- B 1 2 3
- C 1 2
- D 2 3
Answer: A โ 1 then 3
i increments first, so values are 1, 2, 3. When i is 2, continue skips the log. Note the increment comes BEFORE continue here - if it came after, this would loop forever.
continuewhileTracing
Q30. hard
What is the output?
console.log([1,2,3].reduce((a, b) => a + b, 0));
const total = cart.reduce((sum, item) => sum + item.price, 0);
- A 6 - reduce accumulates the array into a single value
- B [1,2,3]
- C 123
- D 0
Answer: A โ 6 - reduce accumulates the array into a single value
reduce runs a callback over each element carrying an accumulator: 0+1=1, 1+2=3, 3+3=6. It is the loop-with-a-running-total expressed as one call.
reduceAccumulator