← Home ← Codex ← DEBT ← Engine
Browse by Category
+ added · updated 7d
← Back to glossary

Spread & Rest Operators

JavaScript ES2015 Beginner
debt(d5/e3/b3/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). ESLint can detect spread-in-hot-loop patterns and shallow-copy assumptions via rules like no-object-spread-in-hot-path (custom/plugin), but the canonical misconception (shallow vs. deep clone) requires code review or runtime testing to catch reliably. Default linters don't flag the shallow-copy trap automatically.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix is explicit: replace `{...obj}` with `structuredClone(obj)` when deep copy is needed. This is a one-to-one substitution within a single expression, no cross-file refactoring required. Performance issues in loops require relocating spread outside the loop or restructuring iteration logic.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Spread and rest are localized syntactic choices within function signatures or object literals. They don't impose system-wide coupling or architectural debt. The burden is cognitive (understanding shallow vs. deep) rather than structural. Each usage site is independent; poor choices don't cascade or force future refactors.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field explicitly states the trap: developers assume `{...obj}` creates a deep clone (as some might expect from the intuitive name 'spread'), but it only spreads top-level properties, leaving nested objects as shared references. This directly contradicts intuition and is a documented gotcha that most JS developers eventually learn through painful debugging.

About DEBT scoring →

Also Known As

spread operator rest parameters destructuring spread

TL;DR

Spread (...) expands iterables into arguments or array/object literals; rest (...) collects remaining arguments into an array.

Explanation

Spread: [...arr] clones array, {...obj} shallow-clones object, fn(...args) spreads into call. Rest: function fn(first, ...rest) collects remaining params. Object spread for merging: {...defaults, ...overrides} — later keys win, parallel to array_merge($defaults, $overrides) in PHP. Spread copies shallow — nested objects are still references. Object spread is not available in PHP natively without spread operator RFC.

Common Misconception

Object spread creates a deep clone — {...obj} is a shallow copy; nested objects are still shared references, exactly like PHP's array spread which also copies shallowly.

Why It Matters

Spread and rest are everywhere in modern JS — understanding shallow copy semantics prevents bugs when merging configuration objects that contain nested arrays or objects.

Common Mistakes

  • Assuming {...obj} deep-clones nested objects
  • Using spread in performance-critical loops — creates new objects each iteration
  • Rest parameters confused with arguments object

Code Examples

✗ Vulnerable
// Mutates original nested object:
const config = { db: { host: 'localhost' } };
const override = { ...config, extra: true };
override.db.host = 'prod'; // Also mutates config.db.host!
✓ Fixed
// Shallow clone — fine for flat objects:
const merged = { ...defaults, ...userConfig };

// Deep clone when needed:
const deepClone = structuredClone(config);

// Rest parameters:
function log(level, ...messages) {
    messages.forEach(m => console[level](m));
}

Added 17 Mar 2026
Edited 22 Mar 2026
Views 69
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings S 1 ping M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 3 pings F 1 ping S 2 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 0 pings M
No pings yet today
No pings yesterday
Scrapy 10 Amazonbot 9 Perplexity 5 Google 4 Ahrefs 4 ChatGPT 4 SEMrush 4 Majestic 2 PetalBot 2 Twitter/X 2 Claude 1 Bing 1 Meta AI 1 Brave Search 1 Applebot 1
crawler 47 crawler_json 4
🧱 FUNDAMENTALS — new to this? Start with the ground floor.
JavaScript javascript The programming language of the browser — it reads and modifies the page (the DOM), reacts to user events, and fetches data without reloading.

JavaScript is the only language browsers execute, so every interactive behaviour on the web goes through it. Its two defining traits — single-threaded event loop and loose typing (== coercion) — explain the majority of both its bugs and its design patterns.

💡 Default to const, use === always, and reach for let only when a value genuinely reassigns.

Ask Codex about JavaScript →
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Use structuredClone() when you need a deep copy — spread is shallow like PHP's array spread
📦 Applies To
javascript ES2015 web cli
🔗 Prerequisites
🔍 Detection Hints
Spread used as deep clone assumption; spread inside hot loop creating unnecessary objects each iteration
Auto-detectable: ✗ No eslint
🤖 AI Agent
Confidence: Low False Positives: High ✓ Auto-fixable Fix: Low Context: Function


✓ schema.org compliant