Destructuring, Spread & Rest

10 questions found

How do you destructure values out of an array?

Beginner
Array destructuring pulls values out by position into named variables using square-bracket syntax on the left side of an assignment.
const [first, second] = [10, 20];
console.log(first, second); // 10 20
Real-world example Unpacking a [value, setValue] pair returned by React's useState hook.

Common follow-ups: How do you skip an element while destructuring an array?

Arrays & Array Methods

How do you destructure properties out of an object?

Beginner
Object destructuring pulls named properties into variables using curly-brace syntax; the variable names must match the property names unless you rename them.
const user = { name: 'Sam', age: 30 };
const { name, age } = user;
console.log(name); // 'Sam'
Real-world example Extracting just the fields you need from a large API response object.

Common follow-ups: How do you rename a destructured variable?

Objects Property Descriptors & Immutability

What does the spread operator (...) do when used on an array?

Beginner
Spread expands an iterable's elements in place, commonly used to copy an array or merge multiple arrays into a new one without mutating the originals.
const a = [1, 2];
const b = [3, 4];
const combined = [...a, ...b]; // [1, 2, 3, 4]
Real-world example Merging a default list of settings with user-provided overrides.

Common follow-ups: Does spreading an array create a deep copy or a shallow copy?

Arrays & Array Methods

How do you assign default values while destructuring?

Intermediate
Add = defaultValue after the variable name; the default is used only when the corresponding value is undefined (not null or any other falsy value).
function greet({ name = 'Guest' } = {}) {
  console.log(`Hello, ${name}`);
}
greet(); // 'Hello, Guest'
Real-world example Providing sensible fallback values for optional configuration object properties.

Common follow-ups: Why does { name = 'Guest' } need = {} as well to avoid an error when called with no arguments?

Functional Programming

How does the rest parameter differ from the spread operator, even though they use the same '...' syntax?

Intermediate
Rest COLLECTS multiple arguments/elements INTO an array (used in function parameters or destructuring patterns); spread EXPANDS an array/iterable OUT into individual elements (used in calls or array/object literals). They're opposite operations sharing identical syntax.
function sum(...nums) { // rest: collects args into an array
  return nums.reduce((a, b) => a + b, 0);
}
sum(...[1, 2, 3]); // spread: expands array into args -> 6
Real-world example Rest to accept a variable number of arguments in a logging function; spread to pass an array of arguments to Math.max().

Common follow-ups: Can rest and spread be used together in the same function?

Functional Programming

How do you use spread to shallow-copy and merge objects?

Intermediate
Spreading an object into a new object literal copies its own enumerable properties; when merging multiple objects, later spreads override earlier ones for matching keys.
const defaults = { theme: 'light', fontSize: 14 };
const overrides = { theme: 'dark' };
const merged = { ...defaults, ...overrides };
// { theme: 'dark', fontSize: 14 }
Real-world example Combining a component's default props with props explicitly passed by the caller.

Common follow-ups: Why is this called a 'shallow' copy, and what problem can that cause with nested objects?

Objects Property Descriptors & Immutability

How do you destructure nested objects and arrays in one statement?

Advanced
Destructuring patterns can be nested to match the shape of complex data, pulling deeply nested values into flat variables in a single expression.
const response = { data: { user: { name: 'Sam' } }, meta: { ids: [1, 2] } };
const { data: { user: { name } }, meta: { ids: [firstId] } } = response;
console.log(name, firstId); // 'Sam' 1
Real-world example Extracting a deeply nested field from a complex GraphQL or REST API response in one line.

Common follow-ups: What happens if an intermediate nested property is undefined during this kind of destructuring?

Error Handling

Why must the rest element be the LAST element in a destructuring pattern?

Advanced
Rest collects 'everything remaining' after the named elements are extracted, so its position only makes sense as the final element — putting it earlier would make the remaining count ambiguous, and JavaScript throws a SyntaxError.
const [first, ...rest] = [1, 2, 3, 4]; // valid: rest = [2,3,4]
// const [...rest, last] = [1,2,3]; // SyntaxError
Real-world example Splitting an array into its head and tail for recursive-style processing.

Common follow-ups: Does the same last-position rule apply to object rest destructuring?

Error Handling

How can you use destructuring to swap two variables without a temporary variable?

Advanced
Array destructuring evaluates the right-hand side array literal fully before assigning, so wrapping both variables in a temporary array and destructuring back swaps them in a single expression.
let a = 1, b = 2;
[a, b] = [b, a];
console.log(a, b); // 2 1
Real-world example A classic interview trick question, occasionally useful in real sorting/swapping algorithm code.

Common follow-ups: How would you have swapped variables before destructuring existed?

Types & Coercion

How do computed property names interact with object destructuring?

Advanced
Wrapping an expression in square brackets inside a destructuring pattern lets you extract a property whose NAME is stored in a variable, rather than being a fixed identifier known ahead of time.
const key = 'name';
const { [key]: value } = { name: 'Sam' };
console.log(value); // 'Sam'
Real-world example Extracting a dynamically-named field, such as a form field whose key comes from configuration data.

Common follow-ups: Is this the same mechanism used for computed property names in object literals?

Objects Property Descriptors & Immutability