Spread operator
Sa novim ES2015 standardom je došao novi operator “…” koji može da razdvoji niz u listu i obrnuto da grupiše listu u niz. U zavisnosti koju funkciju obavlja ovaj parametar ima naziv “spread” ili “rest”. Ukoliko se operator nalazi ispred iteratibilnog objekta i “širi” iterator (npr.niz) u pojedinačne vrednosti praveći listu, onda se naziva “spread”.
Transformacija niza u listu argumenata
Ovaj operator je zamena za često korišćen problem kada je potrebno niz prebaciti u listu argumenata. A najbolji primer je “širenje” niza u listu argumenata funkcije. Ovaj operator se koristi pri pozivanju funkcije:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
function foo (a,b,c){ console.log(a); console.log(b); console.log(c); } argNiz = [1,2,3]; // Problem funkcija ne prihvata niz: foo(argNiz); // Vraća: [1,2,3], undefined, undefined // Stari način rešavanja problema: foo.apply(null, argNiz); // Vraća: 1,2,3 // Novi pristup sa novom sintaksom foo(...argNiz); // Vraća: 1,2,3 |
Deklaracije niza koji sadrži drugi niz
Koristi se u okviru deklaracije niza koji sadrži drugi niz:
1 2 |
var a = [2,3] var b = [1, ...a]; // [1,2,3] |
Kloniranje objekta
Sa novim standardom je dozvoljeno korišećenje spread operatora u okviru object literala. Ova pogodnost nam omogućava da korišćenjem spread operatora jednostavno kloniramo objekte, bez korišćenja metode Object.assign():
1 2 3 |
var obj1 = { foo: 'bar', x: 42 }; var clonedObj = { ...obj1 }; // Vraca: { foo: 'bar', x: 42 } |
Spajanje dva objekta
Korišećenjem spread operatora je olakšano spajanje dva objekta bez dupliranja svojstava:
1 2 3 4 |
var obj1 = { foo: 'bar', x: 42 }; var obj2 = { foo: 'baz', y: 13 }; var mergedObj = { ...obj1, ...obj2 }; // Vraća: { foo: "baz", x: 42, y: 13 } |
Rest operator
Neograničeni broj argumenata kao niz
Rest sintaksa nam dozvoljava da predstavimo neograničeni broj argumenata kao niz. Ovaj operator se koristi pri definisanju funkcije tako što grupiše preostale argumente u niz:
1 2 3 4 |
function nekaFunkcija(x, y, ...ostatak) { console.log("Ovo je višak prosledjenih argumenata: " + ostatak); } nekaFunkcija(3, 5, 8, 6); // Vraća: "Ovo je višak prosledjenih argumenata: 8,6" |
Sakupljen niz može po potrebi da se destruktuira na pojedinačne vrednosti.
1 2 3 4 5 6 7 |
function f(...[a, b, c]) { return a + b + c; } f(1, 2, 3) // Vraća: 6 f(1) // Vraća: NaN (jer su "b" i "c" undefined) f(1, 2, 3, 4) // Vraća: 6 (Četvriti parametr nije destruktuiran jer nema kojoj vrednosti da se dodeli) |
Transformacija liste u niz
Ovaj operator zamenjuje prekomplikovano rešenje koje se koristilo za prebacivanje liste u niz :
1 2 3 4 5 6 7 |
function kvadriranje(a, b, c) { // Stari pristup: var niz = Array.prototype.slice.call(arguments); var kvadrat = niz.map(function (clanNiza){ return clanNiza * clanNiza; }); |
Novi način sa rest operatorom:
1 2 3 4 5 6 7 8 9 |
function kvadriranje(a, b, c) { var niz = [...arguments]; // Stari pristup: var niz = Array.prototype.slice.call(arguments); var kvadrat = niz.map(function (clanNiza){ return clanNiza * clanNiza; }); console.log("Kvadrati brojeva su: " + kvadrat) } kvadriranje(1,2,3); // Vraća: "Kvadrati brojeva su: 1,4,9" |
BONUS: Asocijativnost spread/rest operatora
Svaki JavaScript operator ima svoju “važnost” koja je direktno povezana za asocijativnost i način na koji se odredjuje koja operacija ima prednost u odsustvu zagrada. Sread/Rest operator spada u “slabije” operatore (tj. jedino je slabiji , “zarez” operator). Tabelu značaja operatora pogledajte u članku “JavaScript opertator”.
Primer
U JavaScript svetu možemo da naletimo na sledeći izraz:
1 2 3 4 |
const result = { name: "results"; ...!!data ? : { default: true } }; |
Bitan deo celog ovog izraza je ustvari ovaj teško razumljivo deo:
1 |
...!!data ? : { default: true } |
Da bi se razumeo izraz potrebno je da znamo koji operator ima veći značaj tj. prednost pri izvršavanju izraza. Sledeća lista prikazuje operatore iz ovog izraza prema “značaju”:
- !! (operator negacije)
- … ? … : … (ternarni operator)
- … (spread operator)
Predhodna lista nam odredjuje tok izvrašavanja izraza: prvo se sa duplom negacijom “data” promenjiva konvertuje u logičku vrednost (više o ovome pročitajte u članku “JS snippets (tips & tricks)”). Ukoliko dobijemo TRUE logičku vrednost onda na scenu stupa ternarni operator koji uzima “data” objekat nakon čega ga “raširi” sa spread operatorom, za FALSE vrednost trenarrni operator vraća objekt literal i nje ga raširi sa spread operatorom.