Polub bloga na fejsie!

Pętle JavaScript – dobre praktyki

8

Jak widzisz, tematem dzisiejszego wpisu są pętle JavaScript oraz dobre praktyki z nimi związane. Na temat pętli w języku JavaScript pisałem już co nieco w czasie moich przygotowań do egzaminu 70-480, a konkretnie w artykule „Sterowanie przepływem operacji w języku JavaScript”. Było to jednak dość ogólne potraktowanie tematu, a dziś chciałbym przyjrzeć się temu bliżej i pokazać jak korzystać z tego elementu języka w sposób jak najbardziej wydajny. W niniejszym poście przyjrzymy się przede wszystkim dwie pętle JavaScript: „for” oraz „for-in”, które są najczęściej stosowane.

Pętla for

Opisywana pętla służy przede wszystkim do iterowania po elementach tablic (lub obiektów przypominających tablice czyli kolekcji). Najbardziej rozpowszechnionym sposobem definiowania pętli „for” znanym też z innych języków programowania jest ten widoczny poniżej:

W przypadku tak prostego przykładu może to nie mieć znaczenia ale dla tak napisanej pętli jak w powyższym kodzie, wartość „length” tablicy pobierana jest przy każdym przebiegu pętli. Rozważmy więc drugi, bardziej „życiowy” przykład:

Tutaj nie mamy już do czynienia ze zwykłą tablicą a z obiektem HTMLCollection. W przypadku tego rodzaju obiektów każdorazowe odwołanie do właściwości „length” skutkuje odwołanie się do struktury dokumentu DOM co jest już dużo bardziej kosztowne. W związku z tym, pierwszą dobrą praktyką jest trzymanie długości tablicy w osobnej zmiennej:

Jeśli nie odpowiada nam definiowanie dwóch zmiennych na potrzeby pętli, możemy zamiast tego zastosować iterowanie odwrotne, od wartości maksymalnej do zera:

Oczywiście, ten sam efekt możemy uzyskać za pomocą pętli while:

Należy pamiętać, że przy użyciu dwóch ostatnich przykładów, jako że iteracja odbywa się od tyłu, odwołania do elementów tablicy/kolekcji również odbywają się od tyłu. W związku z tym można je stosować w zależności od konkretnej sytuacji.

Inna sprawa, że narzędzie JSLint zaleca stosowanie zamiast „i++” oraz „i–” wyrażeń w stylu „i = i + 1” albo „i += 1”, jak dla mnie jednak, stosowanie „i++” jest na tyle rozpowszechnione wśród programistów, że każdy wie o co chodzi i nie jest to coś co wprowadzałby niepotrzebną nieczytelność.

Pętla for-in

Drugi rodzaj JavaScript’owych pętli, zwanych też wyliczeniami stosuje się do iteracji po właściwościach obiektów. Rozpocznijmy od przykładu:

Jak widać, funkcja tego rodzaju jest trochę podobna do pętli „foreach” z innych języków programowania, z tym że w każdej iteracji zwracana jest nazwa danej właściwości a nie jej wartość. Dlatego w linii ósmej, chcąc odwołać się do danej wartości, stosowana jest konstrukcja „testObject[prop]” – „prop” zawiera nazwę właściwości.

Ok, wszystko pięknie, tylko że powyższy kod został przygotowany na obsługę tak zdefiniowanego obiektu. A co jeśli ktoś gdzieś rozszerzy obiekt „Object” o dodatkową funkcję sumującą?:

Rozwiązaniem tego problemu (i jednocześnie ogólnie dobrą praktyką podczas pisania pętli „for-in”) jest dodanie do pętli poniższego sprawdzenia:

W opisywanym przypadku, użycie metody „hasOwnProperty” pozwoli na odfiltrowanie wszystkich właściwości (lub funkcji), które nie należą bezpośrednio do obiektu „testObject” (ponieważ zwykle nie chcemy by były one uwzględnione w tego rodzaju pętlach).

Oczywiście jest to tylko dobra praktyka i nie zawsze należy ją stosować. Na pewno istnieją przypadki gdy chcemy w pętli „for-in” pracować na wszystkich właściwościach danego obiektu. Zwykle jednak zależy nam tylko na właściwościach należących bezpośrednio do danego obiektu, a wówczas opisywany test będzie jak znalazł 😉

Pętle JavaScript – podsumowanie

To tyle na dziś jeśli chodzi o pętle w języku JavaScript. Jednocześnie zapraszam do komentowania jeśli ktoś chciałby zaproponować jeszcze jakieś usprawnienia dotyczące pętli 🙂

REACT, REDUX, REACT-ROUTER - KURSY ON-LINE

Chcesz od podstaw poznać tajniki React, Redux oraz react-router? Zapraszam do moich szkoleń on-line:

Przejdź do szkoleń

Uwaga! Obecnie trwa przedsprzedaż kursów - premiera 1 sierpnia 2017!

  • Michał Gruca

    Wg. https://github.com/greg-dev/clean-code-javascript-pl punkt „Nie optymalizuj nadmiernie” nowoczesne przeglądarki radzą sobie z optymalizacją takiego kodu. Dla przykładu poniższe funkcje wywołane na tym wpisie nie dają jednoznacznych efektów

    function inside () {
    var paragraphs = document.getElementsByTagName(‚p’);
    console.time(‚inside’)
    for (var i = 0; i <paragraphs.length; i++){
    x =+ paragraphs[i].innerHTML;
    }
    console.timeEnd('inside')
    }

    function outside () {
    var paragraphs = document.getElementsByTagName('p'),
    x = '', i = 0, max = paragraphs.length;
    console.time('outside')
    for (i; i < max; i++){
    x =+ paragraphs[i].innerHTML;
    }
    console.timeEnd('outside')
    }

    outside: 0.134033203125ms, 0.126708984375ms
    inside: 0.134033203125ms, 0.1328125ms

  • Megrita

    Czytalam to w ksiazce „Javascript. Wzorce” S. Stoyan 😉 Moglbys podac zrodlo tej wiedzy, jest to napisane bardzo podobnie do oryginalu i nawet w tej samej kolejnosci. Niemniej, przydatne.

    • całkiem możliwe, że tak właśnie było – w czasie gdy ten wpis powstawał byłem pod dużym wrażeniem tej właśnie książki… pewnie masz rację i warto podać, że wpis był nią inspirowany! zresztą może napiszę nową wersję tego wpisu tak żeby bardziej przystawał do dzisiejszych standardów…

Google Analytics Alternative