Spread i rest

Spread syntax, to nowy zapis, który umożliwia rozbijanie iterowanej (takiej po której można robić pętle) wartości na składowe.
Co to jest ta iterowana wartość? Może nią być string (bo składa się z poszczególnych liter), może to być tablica (bo składa się z elementów), mogą to być kolekcje (po których bardzo często robiliśmy pętle for) czy nawet obiekty (po których robiliśmy pętle for in).

Poniżej kilka przykładów użycia tego zapisu:


//rozbijanie tablicy na poszczególne liczby
const tab = [1, 2, 3, 4];
console.log(...tab);

//kopiowanie tablic
const tab2 = [...tab];

//łączenie tablic
const tabPart = [3, 4]
const tabFull = [1, 2, ...tabPart, 5, 6]; //1,2,3,4,5,6

//rozdzielanie teksty na poszczególne litery
const str = "Ala ma kota";
const tab = [...str]; //["A", "l", "a", " ", "m", "a", " ", "k", "o", "t", "a"]

Math.max wymaga parametrów po przecinku (nie jako tablica), więc mogę tutaj zastosować spread:


Math.max(...tab);

Spread mogę też wykorzystać do zamiany kolekcji elementów na tablicę:


const divs = document.querySelectorAll('div');

//nowa tablica z samymi tekstami z divów
const texts = [...divs].map(el => {
    return el.innerText;
})

W nowej wersji Javascript spread możemy też zastosować dla obiektów:


const ob1 = {
    a : 10,
    b : 20
}

const ob2 = {
    a : 15,
    c : 30
}

const obBig = {
    ...ob1,
    ...ob2,
    d: 40
};

console.log(obBig); //{ a : 15, b : 20, c : 30, d : 40 }

Rest parameter

Identycznie jak spread syntax wygląda rest parameter, różnicą jest miejsce użycia - w tym przypadku jako parametr funkcji.
Zapis ten umożliwia zbieranie w jedną zmienną (będącą tablicą) wielu parametrów przekazywanych do funkcji:


function myF(...param) {
    console.log(param); //[1, 2, 3, 4, 5]
}

myF(1,2,3,4,5);

function myF(...param) {
    const newTab = [...param];
    newTab.push("Ala");
    console.log(param, newTab); //[1,2,3], [1,2,3,"Ala"]
}

myF(1,2,3);

Tutaj może ci się pojawić pytanie. Po co takie dziwy, skoro poznaliśmy już właściwość arguments, która przecież przechowują przekazane atrybuty:


function myF() {
    console.log(arguments); //1,2,3,4,5
}

myF(1,2,3,4,5);

Po pierwsze właściwość arguments ma narzuconą nazwę, a rest możemy nazywać tak jak nam pasuje. Powyżej nazwaliśmy go param, ale kto nam broni nazwać to inaczej.
Druga różnica jest taka, że do rest parameters trafiają parametry w formie tablicy.
Mimo, że po arguments możemy zrobić pętlę for, nie jest on tablicą (tak samo jak w przypadku kolekcji):


function myF1() {
    arguments.forEach(el => console.log(el));
}
myF1(1,2,3,4,5); //błąd - arguments.forEach is not a function


function myF2(...attr) {
    attr.forEach(el => console.log(el));
}
myF2(1,2,3,4,5); //wszystko ok

Trzecią - najważniejszą zmianą jest to, że do rest możemy bardzo łatwo zbierać "pozostałe atrybuty". Wyobraź sobie, że twoja funkcja wymaga 2 atrybutów, ale ktoś zechce przekazać do niej więcej:


function printAbout(name = "Ala", ...other) {
    console.log("To jest " + name);

    if (other.length) {
        console.log(`${name} ma zwierzaki: ${other.join()}`);
    }
}

printAbout("Marcin", "pies", "kot"); //To jest Marcin. Marcin ma zwierzaki: pies,kot
printAbout(); //To jest Ala

Pamiętaj, że rest musi występować jako ostatni w parametrach:


function myF(a, b, ...numbers) {

}

function myF(a, ...numbers, b) { //błąd : Rest parameter must be last formal parameter

}

Ps. Pewnie zauważyłeś, że lubię kończyć zdania trzema kropkami? Nie ma to nic wspólnego z rest ani spread. Obiecuję. ...Uhh - a raczej U,h,h

Trening czyni mistrza

Jeżeli chcesz sobie potrenować zdobytą wiedzę, to zadania do tego rozdziału znajdują się w w repozytorium pod adresem: https://github.com/kurs-javascript/js-es6 w katalogu 2-spread-rest, przy czym śmiało możesz robić zadania z całego repozytorium.

Dowiedz się więcej na ten temat tutaj.

A może pasuje ci ściągnąć zadania do wszystkich rozdziałów na raz? Jeżeli tak, to skorzystaj z repozytorium pod adresem https://github.com/kurs-javascript/js-all.

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem. Aha - i ta strona korzysta z ciasteczek.