Frontend
easy
mid
Find sum of numbers without a for loop (Hint: reduce() / recursion)
Use Array.prototype.reduce for an iterative, idiomatic one-liner, or recursion (head + sum of tail) for the functional approach. Know the tradeoffs: reduce is O(n)/O(1) and safe; naive recursion is O(n) stack space and risks overflow on large inputs.
4 min read·~8 min to think through
The question tests whether you know functional/declarative alternatives to imperative loops.
Approach 1 — reduce (idiomatic, recommended)
js
const sum = (nums) => nums.reduce((acc, n) => acc + n, 0);- Always pass the initial value
0— without it, an empty array throws. - O(n) time, O(1) space. This is the answer to give first.
Approach 2 — recursion
js
const sum = (nums) =>
nums.length === 0 ? 0 : nums[0] + sum(nums.slice(1));- Base case: empty array → 0. Recursive case: first element + sum of the rest.
- Clean and functional, but:
slicecopies the array each call → O(n²) total; and the call stack grows O(n) → stack overflow on large arrays (JS engines don't reliably do tail-call optimization). - Better recursion uses an index instead of
slice:sum(nums, i + 1)— O(n) time, still O(n) stack.
Other no-loop options
nums.forEach(n => total += n)— technically nofor, but still imperative.- For-of is still a loop.
whileis still a loop. eval(nums.join('+'))— works, never do it (injection, slow).
What interviewers want
Lead with reduce and the 0 initial-value detail. Then show you can do recursion but know its limits — the O(n) stack and overflow risk on large inputs is the real signal. If they push, mention an explicit-stack iterative version or that production code just uses reduce.
Edge cases
- Empty array → 0 (the initial value handles it).
- Non-numbers in the array →
NaNpropagates; validate or coerce if needed. - Very large arrays → recursion overflows;
reduceis fine.
Follow-up questions
- •Why does the naive recursive version risk a stack overflow?
- •Why must you pass 0 as reduce's initial value?
- •How would you make the recursion O(n) instead of O(n^2)?
- •Does JavaScript optimize tail calls?
Common mistakes
- •Omitting reduce's initial value — throws on an empty array.
- •Recursing with slice — O(n^2) and extra allocations.
- •Not mentioning the stack-overflow risk of recursion on large inputs.
- •Reaching for eval.
Performance considerations
- •reduce is O(n) time, O(1) space. Naive recursion with slice is O(n^2) and O(n) stack; index-based recursion is O(n) time but still O(n) stack with overflow risk since JS doesn't reliably do TCO. Prefer reduce in production.
Edge cases
- •Empty array → 0.
- •Array with non-numeric values → NaN.
- •Very large array — recursion overflows, reduce doesn't.
- •Single element.
Real-world examples
- •Summing cart line-item prices, aggregating metric arrays.
Senior engineer discussion
Seniors give reduce immediately (with the initial-value caveat), then demonstrate recursion while explicitly flagging its O(n) stack cost and overflow risk and the lack of reliable TCO in JS. The signal is knowing the tradeoffs, not just producing a no-loop solution.
Related questions
Frontend
Easy
4 min
Frontend
Easy
4 min