for czy forEach

0

Mam na stronie kilka elementów o jakiejś tam nazwie klasy. Chwytam je tak:

const gallery = document.getElementsByClassName("lol");

Chcę teraz przeiterować to, co nie jest tablicą, a obiektem (wg typeOf).

Które rozwiązanie jest lepsze i dlaczego? Oba liczą tyle samo linijek kodu. Nie pytam o czytelność.

// I wersja
for (let i = 0; i < gallery.length; i++)
{
    gallery[i].addEventListener('click', (e) =>
    {
        if (e.target.className == pictureClassName)
        {
             // ...
        }
    });
}
// II wersja
[...gallery].forEach((el) =>
{
    el.addEventListener('click', (e) =>
    {
        if (e.target.className == pictureClassName)
        {
             // ...
        }
    });
});
0

Wydaje mi się, że problem z for jest taki, że dodatkowo trzeba jeszcze przetwarzać indeks elementu. A forEach "leci i nie patrzy".

3
   el.addEventListener('click', (e) =>

Pomijając for/forEach, to ja bym się zastanowił, czy w ogóle ci pętla potrzebna. Czy nie lepiej użyć delegacji zdarzeń i łapać zdarzenie raz, w parencie tych elementów.

Ale być może niekoniecznie, zależy co robisz.

1

Po co Ci pętla, skoro pewnie starczy zwykły listener po klasie obrazka?

3

Obecnie i tak się używa map zamiast for, a prędkość ma tu drugorzędne znaczenie. Optymalizować warto ale gdy coś chodzi wolno.

Map używa się ze względu na krótszy zapis niż pętla for oraz bardziej reużywalny kod. Dla mnie również taki kod jest bardziej czytelny i powoduje mniej błędów, np. w pętli for można się pomylić i pominąć ostatni indeks, a kod wygląda na pierwszy rzut oka ok. W wyrażeniu map sprawa jest jasna i nie ma ryzyka takiego błędu.

Z kolei w przypadku o który pytał op oczywiście pętla jest zbędna tak jak napisał @LukeJL

0

@kosmonauta80: jeden listener na wszystkie obrazki powinien być

1

@Xarviel @marcio

https://stackoverflow.com/a/37576787

Ja nie wiem co tam jest dziwnego, zagmatwanego...

Gdy w JS zadeklarujesz funkcję asynchroniczną to ona rzecz jasna zwraca obiekt Promise. Z kolei w przypadku użycia async await wewnątrz map otrzymamy listę obiektów Promise. Słówko await możemy wołać wyłącznie na najwyższym poziomie modułu JS lub wewnątrz innej funkcji asynchronicznej, zatem nie możemy napisać czegoś takiego jak javascript responses.map(item => await item); ponieważ to nie jest ani na najwyższym poziomie modułu, ani wewnątrz funkcji asynchronicznej, w tym celu musimy właśnie użyć Promise.all() po to aby wywołać resolve na każdym elemencie listy obiektów Promise, który otrzymujemy z map.

Podsumowując async await to fajny cukier składnikowy i sam chętnie z niego korzystam. Ale panowie do licha, używając JS trzeba mieć świadomość, że async await (lub starsze then()) to cukier składniowy, a pod spodem cały czas mamy obiekty klasy Promise, na których trzeba zawołać resolve aby je wykonać/skonsumować. Programując w JS wypadałoby wiedzieć o tym.

Natomiast co do zapisu, to owszem wewnątrz pętli for możemy cały czas cieszyć się cukrem składniowym async await, żaden Promise nam nie wyskakuje i możemy zapomnieć o jego istnieniu, ponieważ wewnątrz pętli for mamy dostęp do kontekstu najwyższego poziomu modułu innymi słowy this wskazuje na global context.

1 użytkowników online, w tym zalogowanych: 0, gości: 1