Само мъртвите риби се движат по течението

Благодарение на ES6 и Babel, писането на JavaScript стана надеждно - от подновения синтаксис на езика до парсването на JSX.  Едно от нещата, които намирам за много удобни в сегашната версия на езика, е spread (...) оператора. Ще направя обзор, за какво той може да се използва.

Извикване на функции без apply

Да кажем, че разполагаме с функция, която приема няколко параметъра. Ако информацията, която трябва да ѝ подадем, е във вид на масив и всеки един елемент от него съответства на аргумент на функцията, то тогава лесно и удобно може да се използва spread оператора, който ще „разпространи“ елементите на масива, превръщайки ги в параметри.

function makeBanitsa (cheese, eggs, yogurt) { }
const ingredientsRatio = [300, 4, 400];

// Тук използваме вградената функция apply
makeBanitsa.apply(null, ingredientsRatio);

Със spread оператора можем да направим същото нещо по следния начин:

// Изпълняване на функцията, извиквайки я с параметри, равни
// съответно на елементите от масива ingredientsRatio
makeBanitsa(...ingredientsRatio);

Ако случайно си изгубил логиката до този момент, нека ти покажа каква е разликата между това да подадеш ingredientsRatio със и без spread оператор.

// Двете извиквания са еквивалентни
makeBanitsa(ingredientsRatio);
makeBanitsa([300, 4, 400]);

// Тук също двете извиквания са еквивалентни
makeBanitsa(...ingredientsRatio);
makeBanitsa(300, 4, 400);

В първия случай функцията makeBanitsa приема 1 аргумент, който е масив, а във втория - 3 аргумента, които са елементи на масива ingredientsRatio.


Комбиниране на масиви

Винаги сме разполагали с множество начини за комбиниране на масиви. Spread операторът предлага един нов такъв. Вече можем да добавяме елементи от друг масив, използвайки директно присвояването на литерала на масива. И нещо повече - елементите от другия масив могат да се намират където и да е в състава на този, който дефинираме. Поне опитах да го обясня по лесен начин.

Ето за какво говоря:

const array1 = [2, 3, 4];
const array2 = [1, ...array1, 5, 6];

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

Копиране на масиви

Преди беше честа практика копирането на масиви да се случва чрез функцията Array.prototype.splice, но вече за тази цел можем да използваме и spread оператора.

const products = ['cheese', 'cottage cheese', 'eggs'];
const productsCopy = [...products];
Важно е да не забравяме, че обектите в масива са записани по референция! Когато копираме масив със spread оператор, не правим копие на пропъртитата на обектите в него.

Трансформиране на аргументи в масив

Подобно на копирането на масиви, използвахме Array.prototype.splice, за да превърнем аргументи на функция в масив. В показания по-долу пример, е използван rest параметър. Той също използва spread оператор. Разликата между spread и rest се изразява в това, че при първия се очаква да имаме събрана информация (напр. в масив), която трябва да „разпръснем“ (напр. под формата на аргументи на функция), а при втория - приемаме разпръсната информация, която се събира в един масив или обект.

// Всички аргументи, с които е извикана функцията
// combineBanitsa, се събират в масив types.
function combineBanitsa(...types) {
    console.log(types);
}

combineBanitsa('сирене', 'спанак', 'щрудел');
// ['сирене', 'спанак', 'щрудел']

Използване на математически функции

Математическите функции в JavaScript в повечето случаи приемат поредица от числа като аргументи. Със spread оператора можем директно да превърнем масив от числа в аргументи.

const numbers = [1, 200, 3000];

console.log(Math.max(...numbers)); // 3000

Деструктуриране + rest параметър

Деструктурирането е често срещана практика, когато искаме да намалим сложността на кода, особено при достигането на дълбоко вложени пропъртита в обекти. То е и изключително използвано, както при разработката на Node.js приложения, така и при пълноценната употреба на всяка известна фронтенд JavaScript библиотека. Нека разгледаме и един пример:

const user = {
    firstName: 'Evlagbi',
    lastName: 'Evlagbiev',
    girlfriend: null
};

const { firstName, ...other } = user;

console.log(firstName);
// Evlagbi


console.log(other);
// {lastName: "Evlagbiev", girlfriend: null}

Деструктурирането представлява записване на стойностите на пропъртита от обект в променливи с имена, същите като тези на пропъртитата. Така например обект, който съдържа пропърти firstName, може да бъде деструктуриран и firstName да се превърне в нормална променлива.

Rest параметърът може да се използва, за да получим обект с пропъртита, същите като онези, които не са директно назовани като firstName. В примера обектът other съдържа пропъртитата lastName и girlfriend, защото firstName е вече е извадено.


Операторът „...“ е нещо, което много често използвам при разработки с JavaScript. Той е доста полезен и за да го прилагаш, трябва да свикнеш с употребата му, когато е необходимо, а преди това - да схванеш как работи. Ако ти е станало интересно, изпробвай го още сега.

Снимка: bTV, Masterchef