Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
••
Sichere ProgrammierungBuilding a Data Audit Workbench That Holds Up in an Assessment(02.10.2026 um 04:03 Uhr)
•
Sichere ProgrammierungFinding the second copy of React that npm ls cannot see(02.10.2026 um 04:07 Uhr)
•
Sichere ProgrammierungBuilding My Own AI Command Center(02.10.2026 um 04:09 Uhr)
•
Sichere Programmierung5 Small SaaS Incident Tests for a Cheap Metrics Dashboard API(02.10.2026 um 04:09 Uhr)
•
Sichere ProgrammierungKontur: an explicit project dashboard for agents, scripts and people(02.10.2026 um 04:10 Uhr)
•
Sichere ProgrammierungWhy I run my company on a Brain and a Hand(02.10.2026 um 04:11 Uhr)
•
Sichere ProgrammierungThe night my post pages scored 39(02.10.2026 um 04:11 Uhr)
••••
Sichere ProgrammierungBuilding a Data Audit Workbench That Holds Up in an Assessment(02.10.2026 um 04:03 Uhr)
•
Sichere ProgrammierungFinding the second copy of React that npm ls cannot see(02.10.2026 um 04:07 Uhr)
•
Sichere ProgrammierungBuilding My Own AI Command Center(02.10.2026 um 04:09 Uhr)
•
Sichere Programmierung5 Small SaaS Incident Tests for a Cheap Metrics Dashboard API(02.10.2026 um 04:09 Uhr)
•
Sichere ProgrammierungKontur: an explicit project dashboard for agents, scripts and people(02.10.2026 um 04:10 Uhr)
•
Sichere ProgrammierungWhy I run my company on a Brain and a Hand(02.10.2026 um 04:11 Uhr)
•
Sichere ProgrammierungThe night my post pages scored 39(02.10.2026 um 04:11 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

When a `for...of` Loop Is Better Than `reduce()`

A few years ago, I was obsessed with reduce(). Every problem looked like a reduction problem. Need a lookup table? users.reduce(...) Need grouping?…

Beitrag
0
Seite
0
↗ Quelle (dev.to)
Social ReaktionenReagiere als Erste:r — dein Feedback zählt!

A few years ago, I was obsessed with reduce().



Every problem looked like a reduction problem.



Need a lookup table?




users.reduce(...)






Need grouping?




users.reduce(...)






Need filtering?




users.reduce(...)






Need transformation?




users.reduce(...)






Need world peace?



Probably:




world.reduce(...)






Eventually I realized something.



The problem wasn't reduce().



The problem was me.



Because while reduce() is incredibly powerful, many developers eventually reach a stage where they start asking a more important question:




Should I even be using reduce() here?




And surprisingly often, the answer is:




No.






Sometimes a simple:




for...of






is easier to read.



Easier to debug.



Faster.



And ultimately the better engineering choice.









The Problem With Loving reduce() Too Much



Developers often discover:




reduce()






and suddenly realize:




It can do everything.






And that's true.



The problem is:




Can do everything

≠

Should do everything






Consider:




const usersById =
users.reduce(
(acc, user) => {
acc[user.id] = user
return acc
},
{}
)






Reasonable.



Many teams would accept this.



Now consider:




const usersById = {}

for (const user of users) {
usersById[user.id] = user
}






Question:




Which one is easier to understand?






For many developers:



The loop.









Cognitive Load Matters



Most discussions around reduce focus on:




Elegance

Composability

Functional Style






But software engineering has another important metric:




Cognitive Load






How much mental effort does it take to understand the code?









Reading A Loop



Most developers instantly understand:




const result = {}

for (const user of users) {
result[user.id] = user
}






Mental model:




Create object

Loop

Add items

Done












Reading A Reduce



Now:




const result =
users.reduce(
(acc, user) => {
acc[user.id] = user
return acc
},
{}
)






You must understand:




Accumulator

Initial State

Return Value

Reducer Contract






Not difficult.



But undeniably more concepts.









The "Everything Is Reduce" Trap



Consider:




const activeUserNames =
users.reduce(
(acc, user) => {
if (user.active) {
acc.push(user.name)
}

return acc
},
[]
)






Works.



But compare:




const activeUserNames = []

for (const user of users) {
if (user.active) {
activeUserNames.push(
user.name
)
}
}






Which is clearer?



Many developers would argue:




The loop.






And that's okay.









The Hidden Mutation Problem



Ironically, many developers use reduce for functional purity.



Then immediately write:




acc.push(...)






or:




acc[user.id] = user






which mutates the accumulator.



Example:




users.reduce(
(acc, user) => {
acc.push(user.name)
return acc
},
[]
)






At this point:




You're already mutating.






So the purity argument disappears.



Now we're mainly comparing:




Reduce

vs

Loop






on readability and performance.









The Immutable Version Is Often Worse



Some developers try:




users.reduce(
(acc, user) => [
...acc,
user.name
],
[]
)






Looks functional.



But now:




New Array

Every Iteration






Which can become extremely expensive.



Especially on large datasets.









Debugging Matters



Imagine debugging:




users.reduce(
(acc, user) => {
...
},
{}
)






versus:




for (const user of users) {
...
}






Where do most developers place breakpoints?



Usually:




Inside the loop.






Loops are naturally procedural.



Debuggers love procedural code.









Performance Matters Too



From the previous article:




Functional Code Can Be Slower






Many reduce implementations involve:




  • callbacks

  • closures

  • allocations

  • intermediate objects



Example:




users.reduce(
(acc, user) => ({
...acc,
[user.id]: user
}),
{}
)






This looks elegant.



But benchmarks terribly.



Compare:




const result = {}

for (const user of users) {
result[user.id] = user
}






Usually much faster.









When reduce() Shines



This article is not anti-reduce.



Far from it.



There are scenarios where reduce is clearly superior.









Scenario 1: Mathematical Aggregation






const total =
prices.reduce(
(sum, price) =>
sum + price,
0
)






Perfect.









Scenario 2: State Evolution






events.reduce(
reducer,
initialState
)






This is literally what reducers were designed for.









Scenario 3: Event Sourcing



From the previous article:




events.reduce(
accountReducer,
initialState
)






Excellent fit.









Scenario 4: Generic Reduction Logic






reduce()






expresses intent very clearly.



You're reducing many values into one.









When for...of Shines









Scenario 1: Building Objects






const map = {}

for (const item of items) {
map[item.id] = item
}






Clear.



Fast.



Obvious.









Scenario 2: Complex Conditional Logic






for (const user of users) {
if (...) {
...
} else if (...) {
...
}
}






Much easier to follow.









Scenario 3: Multiple Side Effects






for (const order of orders) {
updateCache(order)
logOrder(order)
notify(order)
}






Trying to force this into reduce often becomes awkward.









Scenario 4: Early Exit






for (const user of users) {
if (user.id === targetId) {
break
}
}






Reduce cannot naturally stop.



Loops can.









The Senior Developer Perspective



Junior developers often ask:




Which is better?






Senior developers ask:




Which is clearer?






Because maintainability usually dominates.



Not cleverness.



Not elegance.



Not theoretical purity.









The Most Important Rule



Don't optimize for:




Shortest Code






Optimize for:




Most Understandable Code






Future you will thank you.



Your teammates will thank you.



Your debugger will thank you.









Pros Of reduce()






1. Expresses Reduction Clearly









2. Great For State Evolution









3. Excellent For Event Processing









4. Composable









5. Powerful Abstraction









Cons Of reduce()






1. Higher Cognitive Load









2. Easy To Abuse









3. Can Hide Complexity









4. Harder To Debug









5. Often Slower Than Loops









Pros Of for...of






1. Extremely Readable









2. Easy To Debug









3. Supports Early Exit









4. Usually Faster









5. Lower Cognitive Overhead









Cons Of for...of






1. Less Declarative









2. Easier To Introduce Side Effects









3. More Boilerplate









4. Harder To Compose









5. Can Become Procedural Spaghetti



If misused.









The Real Lesson



The biggest mistake developers make with reduce() is treating it like a badge of sophistication.



It's not.



It's a tool.



A very powerful tool.



But still a tool.



Sometimes:




reduce()






is exactly right.



Sometimes:




for...of






is exactly right.



The best engineers don't pick sides.



They pick the clearest solution for the problem in front of them.



And surprisingly often, that solution looks a lot less clever than you might expect.









What's Next?



In the next article we'll discuss:




The Hidden Cost Of Object Spread




Because one innocent-looking pattern:




{
...obj,
newValue
}






has probably caused more accidental JavaScript performance issues than most developers realize.









About The Author



Hi, I'm Amrish Khan.



I enjoy building developer tools, exploring software architecture, and writing about the deeper ideas behind everyday programming concepts.



I'm also building Aruvix — a growing ecosystem of local-first developer tools designed to process data directly in the browser without unnecessary uploads.



Here's a detailed blog on Aruvix:



https://dev.to/amrishkhan05/aruvix-the-ultimate-offline-first-developer-toolkit-e0i



You can follow my work and thoughts here:



Portfolio:

https://www.amrishkhan.dev



LinkedIn:

https://www.linkedin.com/in/amrishkhan



GitHub:

https://www.github.com/amrishkhan05



If you enjoyed this article, consider following for more deep dives into JavaScript, architecture, local-first software, and performance engineering.

🔍 CTI & Forensik

Cyber Threat Intelligence & Forensik

Bedrohungsgraph · ATT&CK-Mapping · Exploit-Belege
IoC Intelligence
1 Indikatoren · Defanged · STIX 2.1
dev[.]to
CTI Threat Relationship Graph
Akteure · Techniken · Beziehungen
3 Knoten · 2 Relationen
CVE / Incident Threat Actor Software MITRE ATT&CK CWE Weakness IoC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten When a `for...of` Loop Is Better Than `reduce()`

Thematisch verwandte Begriffe: When, forof, Loop, Better · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag