Loading...
Loading...
Three dots (...) that expand iterables into individual elements.
Module 9 · Modern JavaScript (ES6+)
ES2015 and later additions transformed how JavaScript is written. let and const, template literals, modules, spread/rest, optional chaining, and nullish coalescing are now standard in every modern codebase.
Learn Spread Operator in JavaScript — covering Array Spread, Object Spread, Copying, Merging with interactive visual examples and step-by-step explanations.
ES2015 (ES6) and the releases that followed added the syntax modern JavaScript is written in today. let and const replaced var, template literals replaced string concatenation, and import/export replaced global script tags.
This module covers the ES6+ features you will see in every codebase and job interview. Each chapter shows the old pattern alongside the modern equivalent so you can read legacy code and write idiomatic JavaScript.
Understanding spread operator is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
Expand an array into individual elements.
// Spread "unpacks" an array: const nums = [1, 2, 3]; console.log(...nums); // 1 2 3 (separate arguments) // Insert into another array: const more = [0, ...nums, 4, 5]; // [0, 1, 2, 3, 4, 5] // Pass array as function arguments: function add(a, b, c) { return a + b + c; } add(...nums); // 6 (same as add(1, 2, 3)) // Math.max with arrays: const scores = [85, 92, 78, 95, 88]; Math.max(...scores); // 95 Math.min(...scores); // 78 // Convert iterable to array: const chars = [..."hello"]; // ["h", "e", "l", "l", "o"] const unique = [...new Set([1, 2, 2, 3])]; // [1, 2, 3]
Copy and extend objects immutably.
// Spread object properties into a new object: const defaults = { theme: "light", lang: "en", debug: false }; const userPrefs = { theme: "dark", lang: "ja" }; const config = { ...defaults, ...userPrefs }; // { theme: "dark", lang: "ja", debug: false } // Later spreads overwrite earlier ones! // Add/override properties: const user = { name: "Alice", age: 25 }; const updated = { ...user, age: 26, email: "a@b.com" }; // { name: "Alice", age: 26, email: "a@b.com" } // Remove a property (with destructuring): const { age, ...withoutAge } = user; // withoutAge = { name: "Alice" } // Conditional properties: const post = { title: "Hello", ...( isPublished && { publishedAt: new Date() }), ...( tags.length && { tags }), };
Spread creates shallow copies — understand the limits.
// Shallow copy of arrays: const original = [1, 2, 3]; const copy = [...original]; copy.push(4); console.log(original); // [1, 2, 3] (unchanged) console.log(copy); // [1, 2, 3, 4] // Shallow copy of objects: const obj = { a: 1, b: 2 }; const clone = { ...obj }; clone.c = 3; console.log(obj); // { a: 1, b: 2 } (unchanged) console.log(clone); // { a: 1, b: 2, c: 3 }
Spread creates a new array/object — modifying the copy doesn't affect the original.
Combine arrays and objects together.
// Merge arrays: const front = ["React", "Vue"]; const back = ["Node", "Django"]; const fullStack = [...front, ...back]; // ["React", "Vue", "Node", "Django"] // Merge + deduplicate: const all = [...new Set([...front, ...back, ...front])]; // Merge objects (last wins): const base = { size: "md", color: "blue", variant: "solid" }; const override = { color: "red", size: "lg" }; const merged = { ...base, ...override }; // { size: "lg", color: "red", variant: "solid" } // Order matters! const a = { x: 1, y: 2 }; const b = { y: 3, z: 4 }; { ...a, ...b } // { x: 1, y: 3, z: 4 } — b's y wins { ...b, ...a } // { x: 1, y: 2, z: 4 } — a's y wins
Real-world uses of spread.
// 1. Immutable state updates (React): const [todos, setTodos] = useState([]); // Add: setTodos([...todos, newTodo]); // Remove: setTodos(todos.filter(t => t.id !== id)); // Update one: setTodos(todos.map(t => t.id === id ? { ...t, done: true } : t)); // 2. Function composition: function withDefaults(options) { return { method: "GET", headers: {}, ...options }; } withDefaults({ url: "/api" }); // { method: "GET", headers: {}, url: "/api" } // 3. Array manipulation without mutation: const arr = [1, 2, 3, 4, 5]; // Prepend: [0, ...arr] // Append: [...arr, 6] // Insert: [...arr.slice(0, 2), 99, ...arr.slice(2)] // Remove: [...arr.slice(0, 1), ...arr.slice(2)] // 4. Convert NodeList to Array: const divs = [...document.querySelectorAll("div")]; divs.map(d => d.textContent); // now array methods work
Common questions about spread operator.