…przynajmniej dla mnie zaskakujący Otóż mam dla ciebie ciekawostkę, wobec której ja nie mogłam przejść obojętnie. Jak tylko ją poznałam – wiedziałam, że muszę posłać ją dalej w świat. I dziś nadszedł ten dzień.
Przecinek jako separator
Z jakim zastosowaniem w JS kojarzy ci się przecinek? Mi na myśl przychodzi przede wszystkim rozdzielanie elementów tablicy, własności obiektu, deklaracji zmiennych, argumentów funkcji. Mówimy wtedy o przecinku jako separatorze.
const arr = [1, 2, 3, 4];
const obj = {x: 5, y: 6};
const a = 7, b = 8, c = 9;
Math.max(10, 100);
Istnieje jednak operator przecinka, którego zastosowanie jest zupełnie inne.
Przecinek jako operator
Według MDN operator przecinka służy do wykonywania kilku wyrażeń (expression) w jednym poleceniu (statement) – po kolei, od lewej do prawej, zwracając wartość z ostatniego wyrażenia.
Brzmi mętnie, jednak przykład wszystko tobie wyjaśni:
const x = (1, 2, 3, 4);
x; // 4
let x, y, z;
x = (y=1, z=4);
x; // 4
y; // 1
z; // 4
const y = ((() => "a")(), (() => "b")());
y; // "b"
const test = () => {
return console.log(y), y;
};
test(); // loguje "b" i zwraca "b"
Jeśli należysz do osób, które teraz myślą „wow, cóż za ciekawostka, nie znałem wcześniej tego operatora…!” to teraz powiem tobie… Raaaaaczej znałeś.
Z pewnością tworzyłeś kiedyś pętle for
z dwoma parametrami. Zauważ, że najprawdopodobniej korzystałeś wtedy z operatora przecinka.
for (var i=0, j=100; i <= 100; i++, j--) {...}
Bardzo często operator przecinka jest używany wewnątrz pętli właśnie w celu zastosowania wielu parametrów. Dzięki niemu wszystkie zmienne (i
oraz j
w powyższym przykładzie) są aktualizowane podczas każdej iteracji.
Ok, skoro rozumiemy sens operatora przecinka, pozostaje tylko jedno pytanie.
Po co tyle nawiasów?
Korzystanie z operatora przecinka często wiąże się z użyciem wielu nawiasów, które na pierwszy rzut oka wyglądają sztucznie. Aby znaleźć ich sens istnienia, należy najpierw zapoznać się z tematem pierwszeństwa operatorów. Przyjrzymy się teraz operatorowi przecinka na poniższym przykładzie:
return 2 * 3 + 4, 5;
Powyższe polecenie posiada 3 operatory: *
, +
oraz ,
. Pierwszeństwo operatorów określa kolejność, w jakiej operatory są ewaluowane. Operator przecinka posiada najniższy poziom pierwszeństwa ze wszystkim operatorów, wobec czego zostanie ewaluowany jako ostatni.
return 2 * 3 + 4, 5;
return 6 + 4, 5;
return 10, 5;
return 5;
Z tą wiedzą wróćmy do przykładu z początku artykułu i sprawdźmy, co się stanie po pominięciu nawiasów. Zauważ, że operator =
posiada wyższy poziom pierwszeństwa niż operator ,
.
const x = 1, 2, 3, 4;
const x, 2, 3, 4;
// SyntaxError: missing variable name
Nawiasy posiadają najwyższy poziom pierwszeństwa. Stosując je mamy pewność, że operator ,
zostanie zastosowany przed operatorem =
.
const x = (1, 2, 3, 4);
// czyli inaczej...
const x = (((1, 2), 3), 4);
x; // 4
Koniecznie daj znać w komentarzu – znałeś ten operator? A co ważniejsze – korzystasz z niego? Czy jest on dla ciebie tylko programistyczną ciekawostką, czy może jednak – praktycznym rozwiązaniem?