JavaScript Programming Labs

Master JavaScript through hands-on coding challenges. Write real code, get instant feedback, and build practical web development skills.

Spread/Rest, Advanced Destructuring & Collections - Module 9

Master modern JavaScript operators and data structures: spread/rest syntax, advanced destructuring patterns, and Set/Map collections.

Lab 25: Spread & Rest Operators
Intermediate
Coding Challenge
Your Task: Master the spread (...) and rest (...) operators - powerful ES6+ features for working with arrays, objects, and function parameters.

Detailed Requirements:

1. Spread arrays - Expand array elements.
// Spread into new array const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const combined = [...arr1, ...arr2]; console.log(combined); // [1, 2, 3, 4, 5, 6] // Add elements while spreading const withMore = [0, ...arr1, 4, 5]; console.log(withMore); // [0, 1, 2, 3, 4, 5] // Copy array (shallow) const copy = [...arr1]; console.log(copy); // [1, 2, 3]
2. Spread objects - Merge and copy objects.
const obj1 = { a: 1, b: 2 }; const obj2 = { c: 3, d: 4 }; // Merge objects const merged = { ...obj1, ...obj2 }; console.log(merged); // { a: 1, b: 2, c: 3, d: 4 } // Override properties (last wins) const updated = { ...obj1, b: 10, e: 5 }; console.log(updated); // { a: 1, b: 10, e: 5 } // Shallow copy const clone = { ...obj1 }; console.log(clone); // { a: 1, b: 2 }
3. Spread in function calls
const numbers = [5, 2, 8, 1, 9]; // Math functions console.log(Math.max(...numbers)); // 9 console.log(Math.min(...numbers)); // 1 // Pass array as arguments function sum(a, b, c) { return a + b + c; } const args = [1, 2, 3]; console.log(sum(...args)); // 6
4. Rest parameters in functions - Collect arguments into array.
// Collect all arguments function sumAll(...numbers) { return numbers.reduce((acc, n) => acc + n, 0); } console.log(sumAll(1, 2, 3)); // 6 console.log(sumAll(1, 2, 3, 4, 5)); // 15 // Named params + rest function greet(greeting, ...names) { return names.map(name => greeting + ", " + name + "!"); } console.log(greet("Hello", "Alice", "Bob", "Charlie")); // ["Hello, Alice!", "Hello, Bob!", "Hello, Charlie!"]
5. Rest in destructuring
// Array destructuring with rest const [first, second, ...rest] = [1, 2, 3, 4, 5]; console.log(first); // 1 console.log(second); // 2 console.log(rest); // [3, 4, 5] // Object destructuring with rest const { name, age, ...others } = { name: "John", age: 30, city: "NYC", job: "Dev" }; console.log(name); // "John" console.log(others); // { city: "NYC", job: "Dev" }
6. Practical use cases
// Remove property from object const user = { id: 1, name: "John", password: "secret" }; const { password, ...safeUser } = user; console.log(safeUser); // { id: 1, name: "John" } // Prepend/append to array const items = [2, 3, 4]; const withFirst = [1, ...items]; // [1, 2, 3, 4] const withLast = [...items, 5]; // [2, 3, 4, 5] // Combine and dedupe (with Set) const a = [1, 2, 3]; const b = [2, 3, 4]; const unique = [...new Set([...a, ...b])]; console.log(unique); // [1, 2, 3, 4]
💡 Pro Tips:
• Spread creates shallow copies - nested objects are still referenced
• Rest must be the last parameter in function/destructuring
• Use spread to avoid mutating original arrays/objects
• Order matters in object spread - later properties override earlier ones

⚠️ Common Mistakes to Avoid:
• Forgetting spread creates shallow copies (nested objects shared)
• Putting rest parameter before other parameters
• Confusing spread (expanding) vs rest (collecting)

Expected Output:
Combined: [1, 2, 3, 4, 5, 6] Merged: { a: 1, b: 2, c: 3 } Max: 9, Min: 1 Sum of all: 15 Rest array: [3, 4, 5]

Requirements Checklist

Use spread to combine/copy arrays
Use spread to merge/copy objects
Use spread in function calls (Math.max, etc.)
Use rest parameters in a function
Use rest in array destructuring
Use rest in object destructuring
Console Output
// Click "Run Code" to execute your JavaScript
Hints & Tips
• Spread arrays: [...arr1, ...arr2]
• Spread objects: { ...obj1, ...obj2 }
• Function spread: Math.max(...numbers)
• Rest params: function fn(...args) { }
• Array rest: const [a, b, ...rest] = arr
• Object rest: const { x, ...rest } = obj
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below

Lab 26: Advanced Destructuring
Intermediate
Coding Challenge
Your Task: Master advanced destructuring patterns - nested destructuring, default values, renaming, and function parameter destructuring.

Detailed Requirements:

1. Nested array destructuring
const matrix = [[1, 2], [3, 4], [5, 6]]; const [[a, b], [c, d]] = matrix; console.log(a, b, c, d); // 1 2 3 4 // Skip elements const [, [, second]] = matrix; console.log(second); // 4 // Mix with rest const [first, ...remaining] = matrix; console.log(first); // [1, 2] console.log(remaining); // [[3, 4], [5, 6]]
2. Nested object destructuring
const user = { name: "John", address: { city: "NYC", zip: "10001", country: { name: "USA", code: "US" } } }; // Nested destructuring const { address: { city, country: { code } } } = user; console.log(city); // "NYC" console.log(code); // "US" // Keep parent + extract nested const { address, address: { zip } } = user; console.log(zip); // "10001" console.log(address); // { city: "NYC", ... }
3. Default values
// Array defaults const [x = 0, y = 0, z = 0] = [1, 2]; console.log(x, y, z); // 1 2 0 // Object defaults const { name = "Guest", role = "user" } = { name: "John" }; console.log(name, role); // "John" "user" // Nested defaults const { settings: { theme = "dark" } = {} } = {}; console.log(theme); // "dark"
4. Renaming (aliasing)
const response = { data: { user_name: "john_doe", user_id: 123 } }; // Rename properties const { data: { user_name: username, user_id: userId } } = response; console.log(username); // "john_doe" console.log(userId); // 123 // Rename with default const { status: httpStatus = 200 } = response; console.log(httpStatus); // 200
5. Function parameter destructuring
// Object parameters function createUser({ name, email, role = "user" }) { return { name, email, role, createdAt: new Date() }; } const user = createUser({ name: "John", email: "john@example.com" }); console.log(user); // Array parameters function getFirstTwo([first, second]) { return { first, second }; } console.log(getFirstTwo([1, 2, 3])); // { first: 1, second: 2 } // With defaults for entire parameter function config({ host = "localhost", port = 3000 } = {}) { return `${host}:${port}`; } console.log(config()); // "localhost:3000" console.log(config({ port: 8080 })); // "localhost:8080"
6. Computed property names and swapping
// Swap variables let a = 1, b = 2; [a, b] = [b, a]; console.log(a, b); // 2 1 // Computed property destructuring const key = "name"; const { [key]: value } = { name: "John", age: 30 }; console.log(value); // "John" // Dynamic extraction function extract(obj, prop) { const { [prop]: value } = obj; return value; } console.log(extract({ x: 10, y: 20 }, "y")); // 20
💡 Pro Tips:
• Use = {} default for optional object parameters
• Rename with originalName: newName
• Combine default + rename: { name: n = "default" }
• Deep defaults need careful nesting

⚠️ Common Mistakes to Avoid:
• Forgetting defaults for nested objects
• Confusing rename syntax (colon vs equals)
• Destructuring undefined without defaults

Expected Output:
Nested: city = "NYC", code = "US" Default: z = 0 Renamed: username = "john_doe" Function param: { name, email, role } Swapped: a=2, b=1

Requirements Checklist

Use nested array destructuring
Use nested object destructuring
Use default values in destructuring
Rename properties while destructuring
Use destructuring in function parameters
Swap variables or use computed properties
Console Output
// Click "Run Code" to execute your JavaScript
Hints & Tips
• Nested array: const [[a, b], [c]] = arr
• Nested object: const { a: { b } } = obj
• Defaults: const { x = 0 } = obj
• Rename: const { oldName: newName } = obj
• Function param: fn({ a, b = 1 })
• Swap: [a, b] = [b, a]
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below

Lab 27: Set & Map Collections
Intermediate
Coding Challenge
Your Task: Master ES6 Set and Map collections - alternatives to arrays and objects for specific use cases like unique values and key-value pairs with any key type.

Detailed Requirements:

1. Create and use Set - Collection of unique values.
// Create a Set const set = new Set(); set.add(1); set.add(2); set.add(2); // Ignored (duplicate) set.add(3); console.log(set); // Set(3) {1, 2, 3} console.log(set.size); // 3 // Create from array const fromArray = new Set([1, 2, 2, 3, 3, 3]); console.log(fromArray); // Set(3) {1, 2, 3} // Check existence console.log(set.has(2)); // true console.log(set.has(5)); // false
2. Set methods and operations
const set = new Set([1, 2, 3, 4, 5]); // Delete elements set.delete(3); console.log(set); // Set(4) {1, 2, 4, 5} // Iterate for (const item of set) { console.log(item); } // forEach set.forEach(item => console.log(item)); // Convert to array const arr = [...set]; // or const arr2 = Array.from(set); // Clear all set.clear(); console.log(set.size); // 0
3. Set use cases - Remove duplicates, membership testing.
// Remove duplicates from array const numbers = [1, 2, 2, 3, 3, 3, 4]; const unique = [...new Set(numbers)]; console.log(unique); // [1, 2, 3, 4] // Fast membership testing const validCodes = new Set(["A1", "B2", "C3"]); console.log(validCodes.has("A1")); // true console.log(validCodes.has("X9")); // false // Set operations (union, intersection) const a = new Set([1, 2, 3]); const b = new Set([2, 3, 4]); const union = new Set([...a, ...b]); // {1,2,3,4} const intersection = new Set([...a].filter(x => b.has(x))); // {2,3} const difference = new Set([...a].filter(x => !b.has(x))); // {1}
4. Create and use Map - Key-value pairs with any key type.
// Create a Map const map = new Map(); map.set("name", "John"); map.set("age", 30); map.set(1, "one"); // Number key console.log(map.get("name")); // "John" console.log(map.get(1)); // "one" console.log(map.size); // 3 // Create from entries const fromEntries = new Map([ ["key1", "value1"], ["key2", "value2"] ]); // Check existence console.log(map.has("name")); // true
5. Map with object/function keys
const map = new Map(); // Object as key (not possible with regular objects!) const user1 = { id: 1 }; const user2 = { id: 2 }; map.set(user1, "Alice's data"); map.set(user2, "Bob's data"); console.log(map.get(user1)); // "Alice's data" console.log(map.get(user2)); // "Bob's data" // Function as key const fn = () => {}; map.set(fn, "function data"); console.log(map.get(fn)); // "function data"
6. Map iteration and conversion
const map = new Map([ ["a", 1], ["b", 2], ["c", 3] ]); // Iterate entries for (const [key, value] of map) { console.log(key, value); } // Iterate keys/values for (const key of map.keys()) console.log(key); for (const val of map.values()) console.log(val); // forEach map.forEach((value, key) => console.log(key, value)); // Convert to arrays const keys = [...map.keys()]; // ["a", "b", "c"] const values = [...map.values()]; // [1, 2, 3] const entries = [...map.entries()]; // [["a",1], ["b",2], ["c",3]] // Map from object const obj = { x: 1, y: 2 }; const mapFromObj = new Map(Object.entries(obj));
💡 Pro Tips:
• Set.has() is O(1) - much faster than array.includes() for large collections
• Map preserves insertion order (like modern objects)
• Use Map when keys are not strings or need to associate data with objects
• WeakSet/WeakMap allow garbage collection of keys

⚠️ Common Mistakes to Avoid:
• Using map[key] instead of map.get(key)
• Forgetting Map returns undefined for missing keys (not error)
• Comparing objects in Set (uses reference, not value equality)

Expected Output:
Set size: 3, unique values Map.get("name"): "John" Unique array: [1, 2, 3, 4] Object key works in Map!

Requirements Checklist

Create a Set and use add/has/delete
Remove duplicates from array using Set
Iterate over a Set (for...of or forEach)
Create a Map and use set/get/has
Use non-string keys in Map (object, number)
Iterate over Map or convert to array
Console Output
// Click "Run Code" to execute your JavaScript
Hints & Tips
• Set: new Set(), .add(), .has(), .delete()
• Unique array: [...new Set(array)]
• Set iterate: for (const x of set)
• Map: new Map(), .set(k, v), .get(k)
• Map object key: map.set(obj, value)
• Map iterate: for (const [k, v] of map)
Progress: 0/6
Score: 0/100
0%

Lab Results

Review feedback below