JS

JavaScript Fundamentals

25 lessons

Progress0%
1. Introduction to JavaScript
1What is JavaScript?2Setting Up Your Environment
2. Variables and Data Types
1Declaring Variables2Data Types3Type Conversion
3. Operators
Arithmetic OperatorsComparison OperatorsLogical Operators
4. Control Flow
Conditional StatementsLoops
5. Functions
Function Basics
6. Arrays & Iteration
Array MethodsSpread, Rest & Destructuring
7. Objects & JSON
Working with ObjectsJSON & Optional Chaining
8. OOP & Classes
Class BasicsInheritance & Private Fields
9. Modules & Modern JS
ES ModulesModern JavaScript Features
10. Async JavaScript
PromisesAsync/Await
11. Error Handling
Error Types & try/catchCustom Errors & Debugging
12. Iterators & Advanced
Iterators & GeneratorsMap, Set & WeakRefs
All Tutorials
JavaScriptArrays & Iteration
Lesson 13 of 25 min
Chapter 6 · Lesson 2

Spread, Rest & Destructuring

Spread, Rest & Destructuring

ES2015 introduced three powerful syntactic features that make working with arrays and objects much more concise: the spread operator, rest parameters, and destructuring assignment.

Spread Operator (...)

The spread operator expands an iterable (array, string, Set, etc.) into individual elements.

Copying and merging arrays:

js
const a = [1, 2, 3];
const b = [4, 5, 6];
const merged = [...a, ...b]; // [1, 2, 3, 4, 5, 6]
const copy   = [...a];       // shallow copy

Spreading into function arguments:

js
Math.max(...[3, 1, 4, 1, 5]); // 5

Rest Parameters

Rest collects remaining function arguments into an array. It must be the last parameter.

js
function sum(first, ...rest) {
  return rest.reduce((acc, n) => acc + n, first);
}
sum(1, 2, 3, 4); // 10

Do not confuse rest parameters (in function signatures) with the spread operator (in call expressions and literals) — they use the same ... syntax but serve opposite purposes.

Array Destructuring

Destructuring lets you unpack array elements into named variables using positional matching.

js
const [x, y, z] = [10, 20, 30];
const [head, ...tail] = [1, 2, 3, 4]; // head=1, tail=[2,3,4]
const [a = 0, b = 0] = [5];           // a=5, b=0 (default)

You can skip elements with commas: const [,second] = [1, 2, 3];

Object Destructuring

Object destructuring unpacks by property name rather than position.

js
const { name, age } = { name: "Alice", age: 30, city: "NY" };
// Rename: { name: fullName }
// Default: { score = 0 }

Nested destructuring:

js
const { address: { city } } = { address: { city: "London" } };

In function parameters:

js
function greet({ name, title = "User" }) {
  return `Hello, ${title} ${name}!`;
}

Spread with Objects

Object spread (ES2018) merges objects and creates shallow copies:

js
const defaults = { theme: "light", lang: "en" };
const config   = { ...defaults, lang: "fr" }; // lang overridden

Code Examples

Spread Operatorjavascript
// Merging arrays
const fruits  = ["apple", "banana"];
const veggies = ["carrot", "broccoli"];
const food    = [...fruits, "grape", ...veggies];
console.log(food);

// Shallow copy (no mutation of original)
const original = [1, 2, 3];
const copy = [...original];
copy.push(4);
console.log("Original:", original);
console.log("Copy:", copy);

// Spread into Math functions
const numbers = [34, 7, 23, 32, 5, 62];
console.log("Max:", Math.max(...numbers));
console.log("Min:", Math.min(...numbers));

Spread expands an array in place. Because the spread creates a new array, pushing to copy does not affect the original.

Rest Parametersjavascript
// Rest collects remaining args into an array
function logAll(label, ...items) {
  console.log(label + ":", items);
  console.log("Count:", items.length);
}

logAll("Colors", "red", "green", "blue");
logAll("Numbers", 1, 2, 3, 4, 5);

// Combining rest with destructuring
function first3([a, b, c, ...rest]) {
  console.log("First:", a, b, c);
  console.log("Rest:", rest);
}

first3([10, 20, 30, 40, 50]);

Rest parameters gather any number of trailing arguments into a real array. You can combine rest with destructuring for expressive parameter handling.

Destructuring Arrays & Objectsjavascript
// Array destructuring with defaults and skipping
const [first, , third = 99] = [10, 20];
console.log(first, third); // 10 99

// Swap variables without temp
let x = 1, y = 2;
[x, y] = [y, x];
console.log("Swapped:", x, y);

// Object destructuring with renaming and defaults
const user = { name: "Bob", role: "admin" };
const { name: userName, role, age = 25 } = user;
console.log(userName, role, age);

// Nested object destructuring
const config = { db: { host: "localhost", port: 5432 } };
const { db: { host, port } } = config;
console.log(`${host}:${port}`);

// Destructuring in function params
function display({ title, year = "unknown" }) {
  console.log(`${title} (${year})`);
}
display({ title: "Inception", year: 2010 });
display({ title: "Draft" });

Destructuring makes variable extraction terse and readable. Defaults handle missing values gracefully, renaming avoids name collisions, and nested destructuring reaches into deep structures in a single expression.

Quick Quiz

1. What does the rest parameter syntax (...args) do in a function definition?

2. What is printed by: const [a, , b] = [1, 2, 3]; console.log(a, b);

3. Which statement correctly merges two objects, with obj2 properties overriding obj1?

Was this lesson helpful?

PreviousNext