JavaScript · Синтаксис · Проміжний

Деструктуризація і spread

10 завдань

Витягуйте значення з масивів та об'єктів в одному рядку. Охоплює деструктуруючі присвоєння, оператор spread та rest-параметри.

Деструктуризація масиву та об'єкта: дефолти, вкладеність, перейменування

#
Деструктуризація дозволяє витягувати значення з масивів і об'єктів у іменовані змінні одним лаконічним виразом. **Деструктуризація масиву** ```javascript const [a, b, c] = [1, 2, 3]; // a=1, b=2, c=3 // Пропустити елементи через порожні слоти const [first, , third] = [10, 20, 30]; // first=10, third=30 // Значення за замовчуванням — використовуються коли значення undefined const [x = 0, y = 0] = [5]; // x=5, y=0 (y використовує дефолт, бо array[1] — undefined) // Обміняти дві змінні без тимчасової let m = 1, n = 2; [m, n] = [n, m]; // m=2, n=1 ``` **Деструктуризація об'єкта** ```javascript const { name, age } = { name: 'Alice', age: 30, role: 'admin' }; // name='Alice', age=30 (role ігнорується) // Перейменувати при деструктуризації const { name: userName, age: userAge } = user; // userName='Alice', userAge=30 // Значення за замовчуванням const { host = 'localhost', port = 3000 } = config; // Перейменування + дефолт const { timeout: ms = 5000 } = options; ``` **Вкладена деструктуризація** ```javascript const { address: { city, zip } } = { name: 'Alice', address: { city: 'Kyiv', zip: '01001' }, }; // city='Kyiv', zip='01001' // Вкладений масив const [[a, b], [c, d]] = [[1, 2], [3, 4]]; ``` **Деструктуризація в параметрах функції** ```javascript // Замість: function greet(user) { const { name, age } = user; ... } function greet({ name, age = 25 }) { return `${name} is ${age}`; } greet({ name: 'Bob' }); // 'Bob is 25' // З масивами: function first([head]) { return head; } first([10, 20, 30]); // 10 ``` **Поширена помилка: деструктуризація null/undefined** ```javascript const { name } = null; // TypeError: Cannot destructure property 'name' of null // Безпечно з дефолтом: const { name } = user ?? {}; ```

Rest-параметри, spread у масивах і об'єктах, пастка поверхневої копії

#
**Rest у деструктуризації — зібрати залишок** ```javascript // Rest масиву const [head, ...tail] = [1, 2, 3, 4]; // head=1, tail=[2, 3, 4] // Rest об'єкта — зібрати всі не деструктуровані ключі const { name, ...rest } = { name: 'Alice', age: 30, role: 'admin' }; // name='Alice', rest={ age: 30, role: 'admin' } ``` **Rest в параметрах функції** ```javascript function sum(...nums) { return nums.reduce((a, b) => a + b, 0); } sum(1, 2, 3, 4); // 10 function log(level, ...messages) { messages.forEach(m => console.log(`[${level}]`, m)); } log('INFO', 'starting', 'ready'); // [INFO] starting [INFO] ready ``` **Spread оператор — розгорнути ітерований об'єкт у окремі елементи** ```javascript // Розгорнути масив як аргументи функції Math.max(...[3, 1, 4, 1, 5]) // 5 // Об'єднати масиви const a = [1, 2, 3]; const b = [4, 5, 6]; const c = [...a, ...b]; // [1, 2, 3, 4, 5, 6] const d = [0, ...a, 99]; // [0, 1, 2, 3, 99] // Поверхнева копія const copy = [...a]; // [1, 2, 3] — новий масив ``` **Spread з об'єктами** ```javascript const base = { x: 1, y: 2 }; const extended = { ...base, z: 3 }; // { x: 1, y: 2, z: 3 } const overridden = { ...base, x: 99 }; // { x: 99, y: 2 } — останній перемагає // Злиття об'єктів const defaults = { color: 'red', size: 'M' }; const config = { size: 'L', weight: 'heavy' }; const merged = { ...defaults, ...config }; // { color: 'red', size: 'L', weight: 'heavy' } ``` **Spread — поверхнева копія: вкладені об'єкти все ще спільні** ```javascript const original = { a: 1, nested: { b: 2 } }; const copy = { ...original }; copy.a = 99; // original.a все ще 1 - OK copy.nested.b = 99; // original.nested.b ТАКОЖ 99 - спільне посилання! // Глибока копія: використовуй structuredClone() або JSON-кругопоїздку const deepCopy = structuredClone(original); ``` **Object.assign vs spread** `Object.assign(target, source)` мутує `target`. Spread завжди створює новий об'єкт. Перевагу надавай spread. ```javascript Object.assign({}, defaults, config) // те саме, що { ...defaults, ...config } Object.assign(obj, patch) // мутує obj на місці ```

Практичні патерни: обмін, minMax, omit, pick, злиття конфігурацій

#
**Обміняти дві змінні** ```javascript let a = 1, b = 2; [a, b] = [b, a]; // a=2, b=1 ``` **minMax одним рядком** ```javascript function minMax(arr) { return [Math.min(...arr), Math.max(...arr)]; } const [min, max] = minMax([3, 1, 4, 1, 5, 9]); // min=1, max=9 ``` **Видалити властивість з об'єкта (без мутації)** ```javascript function omit(obj, ...keys) { const keysToOmit = new Set(keys); return Object.fromEntries( Object.entries(obj).filter(([k]) => !keysToOmit.has(k)) ); } // Скорочено через rest-деструктуризацію: const { password, ...safeUser } = user; // safeUser має все крім password ``` **Вибрати конкретні властивості** ```javascript function pick(obj, ...keys) { return Object.fromEntries(keys.map(k => [k, obj[k]])); } pick({ a: 1, b: 2, c: 3 }, 'a', 'c'); // { a: 1, c: 3 } ``` **Злиття дефолтів з конфігурацією користувача** ```javascript const DEFAULT_CONFIG = { timeout: 3000, retries: 3, verbose: false }; function createClient(userConfig = {}) { const config = { ...DEFAULT_CONFIG, ...userConfig }; // значення користувача перекривають дефолти; відсутні використовують дефолти return config; } createClient({ timeout: 5000 }); // { timeout: 5000, retries: 3, verbose: false } ``` **Spread з ітерованими (не лише масивами)** ```javascript // Розгорнути Set у масив для дедублікації const unique = [...new Set([1, 2, 2, 3, 3])]; // [1, 2, 3] // Розгорнути рядок у символи const chars = [... 'hello']; // ['h', 'e', 'l', 'l', 'o'] // Розгорнути записи Map const m = new Map([['a', 1], ['b', 2]]); const obj = Object.fromEntries([...m]); // { a: 1, b: 2 } ```
01

Деструктуризація масиву

#

Напишіть функцію, яка приймає масив з принаймні трьох елементів і повертає об'єкт з властивостями first, second і rest (масив решти елементів). Використайте деструктуризацію масиву.

function splitArray(arr) {

}

console.log(splitArray([1, 2, 3, 4, 5]));
Рішення
function splitArray(arr) {
    const [first, second, ...rest] = arr;
    return { first, second, rest };
}

console.log(splitArray([1, 2, 3, 4, 5]));
02

Деструктуризація об'єкта

#

Напишіть функцію, яка приймає об'єкт користувача (з властивостями name, age та email) і повертає рядок-привітання, використовуючи лише name і age. Використайте деструктуризацію об'єкта в параметрах функції.

function greetUser({ name, age }) {

}

console.log(greetUser({ name: "Alice", age: 30, email: "[email protected]" }));
Рішення
function greetUser({ name, age }) {
    return `Hello, ${name}! You are ${age} years old.`;
}

console.log(greetUser({ name: "Alice", age: 30, email: "[email protected]" }));
03

Обмін змінних

#

Напишіть функцію, яка приймає два значення і повертає їх у зміненому порядку. Використайте деструктуризацію масиву для обміну в одному рядку.

function swap(a, b) {

}

console.log(swap(1, 2));
console.log(swap("hello", "world"));
Рішення
function swap(a, b) {
    [a, b] = [b, a];
    return [a, b];
}

console.log(swap(1, 2));
console.log(swap("hello", "world"));
04

Об'єднання об'єктів

#

Напишіть функцію, яка приймає два об'єкти і повертає новий об'єкт, що містить усі властивості обох. Якщо властивість є в обох, перемагає значення другого об'єкта. Використайте оператор spread.

function mergeObjects(obj1, obj2) {

}

console.log(mergeObjects({ a: 1, b: 2 }, { b: 3, c: 4 }));
Рішення
function mergeObjects(obj1, obj2) {
    return { ...obj1, ...obj2 };
}

console.log(mergeObjects({ a: 1, b: 2 }, { b: 3, c: 4 }));
05

Клонування та оновлення

#

Напишіть функцію, яка приймає об'єкт користувача і нове ім'я, та повертає новий об'єкт — копію користувача з оновленим іменем. Не змінюйте оригінал. Використайте оператор spread.

function updateName(user, newName) {

}

const user = { name: "Alice", age: 30, role: "admin" };
const updated = updateName(user, "Bob");
console.log(user);
console.log(updated);
Рішення
function updateName(user, newName) {
    return { ...user, name: newName };
}

const user = { name: "Alice", age: 30, role: "admin" };
const updated = updateName(user, "Bob");
console.log(user);
console.log(updated);
06

Значення за замовчуванням у деструктуризації

#

Напишіть функцію, яка приймає об'єкт конфігурації і повертає об'єкт налаштувань із застосованими значеннями за замовчуванням: theme за замовчуванням 'light', fontSize — 16, language — 'en'.

function applyDefaults(config) {

}

console.log(applyDefaults({ theme: 'dark' }));
console.log(applyDefaults({ fontSize: 20, language: 'uk' }));
Рішення
function applyDefaults({ theme = 'light', fontSize = 16, language = 'en' } = {}) {
    return { theme, fontSize, language };
}

console.log(applyDefaults({ theme: 'dark' }));
console.log(applyDefaults({ fontSize: 20, language: 'uk' }));
07

Spread у виклику функції

#

Напишіть функцію, яка приймає масив чисел і повертає найбільше з них, використовуючи Math.max() з оператором spread (Math.max не приймає масив безпосередньо).

function maxValue(numbers) {

}

console.log(maxValue([3, 1, 4, 1, 5, 9, 2, 6]));
Рішення
function maxValue(numbers) {
    return Math.max(...numbers);
}

console.log(maxValue([3, 1, 4, 1, 5, 9, 2, 6]));
08

Rest-параметри

#

Напишіть функцію sum(...numbers), яка приймає будь-яку кількість аргументів і повертає їхню суму.

function sum(...numbers) {

}

console.log(sum(1, 2, 3));
console.log(sum(10, 20, 30, 40, 50));
Рішення
function sum(...numbers) {
    return numbers.reduce((acc, n) => acc + n, 0);
}

console.log(sum(1, 2, 3));
console.log(sum(10, 20, 30, 40, 50));
09

Перейменування при деструктуризації

#

Напишіть функцію, яка приймає об'єкт продукту (з властивостями 'name' і 'price') і повертає новий об'єкт з перейменованими властивостями 'title' і 'cost'. Використайте деструктуризацію з перейменуванням.

function renameProduct(product) {

}

console.log(renameProduct({ name: "Widget", price: 9.99 }));
Рішення
function renameProduct(product) {
    const { name: title, price: cost } = product;
    return { title, cost };
}

console.log(renameProduct({ name: "Widget", price: 9.99 }));
10

Об'єднання масивів без дублікатів

#

Напишіть функцію, яка приймає два масиви і повертає новий масив з усіма унікальними значеннями обох у порядку (без дублікатів). Використайте spread і Set.

function uniqueMerge(arr1, arr2) {

}

console.log(uniqueMerge([1, 2, 3, 4], [3, 4, 5, 6]));
Рішення
function uniqueMerge(arr1, arr2) {
    return [...new Set([...arr1, ...arr2])];
}

console.log(uniqueMerge([1, 2, 3, 4], [3, 4, 5, 6]));