Destructuring & Spread (JS)
debt(d3/e1/b1/t5)
Closest to 'default linter catches the common case' (d3). ESLint (listed in detection_hints.tools) has rules like prefer-destructuring that flag verbose property access patterns that could be destructured. TypeScript can also catch type-level issues. The common misuse (not destructuring when you should) is reliably caught by default or near-default linting configurations.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix confirms this: swapping `const name = user.name; const age = user.age;` for `const {name, age = 0} = user` is a single-line replacement. Adding default values or rest collection is equally minimal. No cross-file changes required.
Closest to 'minimal commitment' (b1). Destructuring is a localized syntax choice at the variable declaration site. It imposes no structural commitment on other files, components, or future maintainers beyond the immediate line of code. It's a naming/extraction convention with negligible downstream weight.
Closest to 'notable trap (a documented gotcha most devs eventually learn)' (t5). The misconception field explicitly states the key trap: developers believe destructuring creates a deep copy, but it only unpacks references — mutating a destructured nested object mutates the original. This is a well-documented gotcha that catches most JS developers at least once, but it's not architecturally catastrophic and is learnable.
Also Known As
TL;DR
Explanation
Array destructuring: const [first, , third] = arr — skips can use empty slots; rest elements: const [head, ...tail] = arr. Object destructuring: const { name, age = 18 } = person — default values for absent keys; rename: const { name: userName } = person; nested: const { address: { city } } = user. Spread in arrays: const merged = [...arr1, ...arr2]; in objects (ES2018): const copy = { ...obj, newProp: 1 } — shallow clone with override. Function parameters: function process({ id, name }) {} — named parameter pattern. Rest in objects: const { id, ...rest } = record — omit known keys. Compared to PHP 8.1 array unpacking and named arguments, JS destructuring is more flexible and widely used.
Diagram
flowchart LR
subgraph Object_Destructuring
OBJ[const user = name email role]
OBJ -->|destructure| VARS[const name email = user]
VARS -->|rename| RENAME[const n: name = user]
VARS -->|default| DEFAULT[const role = admin = user]
end
subgraph Array_Destructuring
ARR[const arr = 1 2 3]
ARR -->|destructure| AVALS[const a b c = arr]
ARR -->|skip| SKIP[const a _ c = arr]
ARR -->|rest| REST[const first ...others = arr]
end
subgraph Function_Params
FN[function greet name greeting = Hi]
FN -->|called with| CALL[greet name: Alice]
end
style OBJ fill:#6e40c9,color:#fff
style ARR fill:#1f6feb,color:#fff
style FN fill:#238636,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Not using default values in destructuring when a property may be missing: const { name = 'Guest' } = user.
- Nested destructuring that becomes hard to read — extract intermediate variables for deeply nested structures.
- Array destructuring for associative data that would be clearer as object destructuring.
- Not using rest in destructuring: const { id, ...rest } = user to separate one property from the rest.
Code Examples
// Manual property access — verbose:
const name = user.name;
const email = user.email;
const city = user.address.city;
// Destructuring:
const { name, email, address: { city } } = user;
// With rename and default:
const { name: fullName, role = 'user' } = user;
// Swap without temp variable
[a, b] = [b, a];
// Object rest — strip id from record
const { id, ...payload } = record;
// Default + rename
const { timeout: ms = 3000, retries = 3 } = options;