Imperative for/while loops where filter, map, and reduce concerns are mixed by hand — the reader must mentally execute the body to learn what's being produced.
Filter / map / reduce expresses the transformation as a sequence of named operations; intent reads in domain language.
Before the refactoring
const seniors = [];for (const u of users) {if (u.age >= 65) seniors.push(u.name);}
After the refactoring
const seniors = users.filter(u => u.age >= 65).map(u => u.name);
Off-by-one errors and accumulator bugs hide in the body and only surface at test time; intent is buried under the mechanism.
Pipelines add a tiny per-element function-call overhead — usually negligible, but profile if the call is on a hot path.
Off-by-one and accumulator bugs vanish; each step is independently testable.
Forcing every loop into a pipeline — including ones with early-exit, side-effect accumulators, or genuinely sequential dependencies — produces .reduce() bodies harder to read than the original.