Księgarnia PWN

   

   

   

   

   

   

   

   

.

.

Bezpłatny newsletter


Underscore.js.

Underscore.js.

Underscore.js jest to biblioteka dostarczająca nam użytecznych funkcji podczas pracy w Java Scripcie. Wiem, bardzo dokładna i wyczerpująca definicja. A tak na poważnie, jest to biblioteka dostarczająca nam narzędzia pozwalające na poprawę naszej pracy podczas wykonywania codziennych prac programistycznych. Oferuje nam ona około 80 funkcji, które mają za zadanie uprościć i zoptymalizować naszą pracę. Skupiają się one głównie na tematyce zarządzania kolekcjami, obiektami oraz przygotowanymi przez nas funkcjami. Jeden z moich przyjaciół podczas rozmowy na temat underscore.js powiedział, że „jest to taki Linq przeniesiony do Java Script-u”. Na pewno porównanie to ma w sobie trochę sensu. Jak dużo, to pozostawiam już ocenie własnej, każdego czytelnika.

Dlaczego warto poznać Underscore.js?

Powodów można by wymienić wiele. Postaram się skupić na kilku z nich, które trafiają do mnie najbardziej. Po pierwsze, zawsze warto uczyć się nowych rzeczy i poznawać nowe sposoby spojrzenia na problemy nawet doskonale nam już znane. Dzięki temu zawsze jest szansa, że nauczymy się czegoś ciekawego. Po drugie, operacje na kolekcjach są czymś, czego chyba nikomu z nas nie uda się nigdy uniknąć. Skoro i tak musimy robić to ciągle, róbmy to zarówno możliwie szybko, optymalnie i jednocześnie bezboleśnie. W omawianej bibliotece otrzymujemy cały zestaw funkcji, które w większości napotykanych scenariuszy na pewno znajdą zastosowanie. Po trzecie, bardzo uproszczone i bogate zarządzanie zarówno pojedynczymi obiektami, jak i całymi ich kolekcjami. Tak wiem, zupełnie jest wspomniane przed chwilą Linq-u. Po czwarte, albo nie, w sumie już wystarczy. Przejdźmy do właściwej prezentacji tego, co chciałbym przekazać w tym artykule.

Dlaczego?

Underscore.js znalazł się tutaj z bardzo prostego powodu. Jest on rozwiązaniem bardzo użytecznym i poprawiającym tempo oraz jakoś pracy każdego programisty JavaScript-u. To chyba wystarczy, jeżeli chodzi o wyjaśnienia.

Instalacja Underscore.js

Jeżeli chodzi o underscore.js to możemy powiedzieć, że słowo instalacja w tym przypadku zostało użyte bardzo na wyrost. Wynika to głównie z faktu, że jest to tak naprawdę tylko jeden plik. Plik ten możemy znaleźć na domowej stronie projektu, czyli pod adresem: http://underscorejs.org/. Znajduje się tutaj oczywiście o wiele więcej, niż tylko pliki z biblioteką, ale my obecnie skupimy się tylko na nich.

W momencie pisania artykułu na stronie projektu mogliśmy wybierać z trzech rodzajów materiałów do pobrania. Pierwszym z nich jest Development Version (1.5.1). Jest to pełna wersja biblioteki. Powinniśmy jej używać, kiedy pracujemy nad czymś lokalnie. Dzięki temu, w każdej chwili możemy prześledzić sposób implementacji każdej części biblioteki. Co prawda można to też zrobić, jeżeli ktoś jest bardzo uparty, na wersji zminimalizowanej. Wersję tę możemy pobrać klikając na Production Version (1.5.1). Jeżeli ktoś jeszcze nie miał do czynienia z praktyką wystawiania dwóch wersji bibliotek Java Script, to chodzi w niej tylko o to, aby na środowisko produkcyjne wrzucać jak najmniej kodu. Dzięki czemu nasze rozwiązanie będzie nadal działało poprawnie, ale ładować się będzie szybciej. Proces taki nazywa się obfuskacją (zaciemnianiem) kodu. Ostatnim, trzecim plikiem, jaki możemy pobrać jest Edge Version. Jest to wersja, nad którą właśnie toczą się prace i która nie została jeszcze oficjalnie wystawiona. Krytycznie niewskazane jest korzystanie z niej podczas tworzenia rozwiązań przeznaczonych komercyjnie, w których stabilność jest rzeczą absolutnie bezdyskusyjną. Polecam natomiast korzystanie z niej w celach edukacyjnych i kiedy programujemy po prostu dla siebie. Wystarczy teraz wybrać plik, który nas interesuje, zapisać go i dodać odniesienie do niego w potrzebnym projekcie. Nic prostszego.

Zanim przejdziemy do praktycznych przykładów chciałbym pokazać, jak drastycznie różni się wygląd funkcji w wersji pełnej od tego w wersji produkcyjnej i co za tym idzie, dlaczego analiza tego drugiego jest zajęciem dla bardzo wytrwałych. Pokażę to na przykładzie funkcji each.

Listing 1. Implementacja funkcji each w pełnej wersji

// The cornerstone, an ‘each‘ implementation, aka ‘forEach‘.

// Handles objects with the built-in ‘forEach‘, arrays, and raw objects.

// Delegates to **ECMAScript 5**’s native ‘forEach‘ if available.

var each = _.each = _.forEach = function(obj, iterator, context) {

if (obj == null) return;

if (nativeForEach && obj.forEach === nativeForEach) {

obj.forEach(iterator, context);

} else if (obj.length === +obj.length) {

for (var i = 0, l = obj.length; i < l; i++) {

if (iterator.call(context, obj[i], i, obj) === breaker) return;

                 }

} else {

for (var key in obj) {

if (_.has(obj, key)) {

if (iterator.call(context, obj[key], key, obj) === breaker) return;

                              }

                 }

               }

  };

Listing 2. Implementacji funkcji each w wersji produkcyjnej

j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(j.has(n,a)&&t.call(e,n[a],a,n)===r)return};

Jak widać już na pierwszy rzut oka, druga wersja jest praktycznie nieczytelna. Złożyło się na to zarówno odpowiednie formatowanie pisanego przez nas kodu, jak i stosowanie możliwie najmniejszych nazw używanych przez nas zmiennych. Otrzymaliśmy oczywiście dzięki temu znaczne zmniejszenie wagi pliki. Natomiast pierwsza przedstawiona wersja jest w pełni czytelna i przejrzysta. Możemy prześledzić zarówno sposób implementacji, jak i zapoznać się z komentarzami pozostawionymi przez autora.

Mógłbym w tym momencie stworzyć stronę internetową, dodać do niej underscore.js i na tym prezentować przykłady jego możliwość. Przedstawienie możliwości odbędzie się przy użyciu jsfiddle.net. Cóż to w ogóle takiego? Jest narzędzie/strona, która pozwala nam na testowanie i tworzenie tymczasowych rozwiązań z zakresu technologii webowych. Możemy ją znaleźć pod adresem http://jsfiddle.net/. Wejdźmy więc na nią i zobaczmy, co możemy tam znaleźć.

1

Rysunek 1. Strona projektu jsfiddle.net

Omówmy sobie pokrótce, co widzimy na stronie. Elementem szczególnie rzucającym się w oczy, są cztery okna zajmujące niemalże całość strony. Pierwszym z nich jest miejsce przeznaczone na HTML, tworzący nasza stroną. W tym momencie warto też wspomnieć, że wypełnianie któregokolwiek z pól jest opcjonalne i można korzystać tylko z tych, które nas w danym momencie interesują. Następnie widzimy miejsce na CSS. Funkcji tej części raczej nie trzeba nikomu objaśniać. Ostatnim z miejsc do wprowadzania danych jest okno JavaScript-u. Umieszczamy tutaj skrypt, który chcemy, aby był wykonany na naszej stronie. Oczywiście z racji na specyfikę omawianego tematu, to właśnie w nim będziemy wykonywać większość naszej najbliższej pracy. Ostatnim oknem, które co prawda nie służy do bezpośredniego wprowadzania treści, jest okno result. My postaramy się z niego nie korzystać i efekty naszej pracy obserwować w narzędziu developerskim. W tym przypadku będzie to narzędzie dostarczone nam razem z przeglądarką Google Chrome. Można ją uruchomić, przyciskając F12.

Zanim jednak to omówimy, przynajmniej pobieżnie, co jeszcze w narzędziu jsfiddle. Skupmy się teraz na jego górnej belce. Kolejno od lewej strony widzimy tam najpierw przycisk Run. Jak łatwo się domyśleć, służy on do uruchamiania przygotowanych przez nas materiałów. Następnie mamy przycisk Save. I tu robi się już ciekawie. Ponieważ dzięki niemu możemy zapisać przygotowany przez nas projekt, np. do późniejszej rozbudowy, czy też do przesłania komuś, jako materiał poglądowy. Kolejne dwa elementy pomagają w tworzeniu lepszego kodu. Pierwszy z nich (TidyUp) pomaga w uporządkowaniu tego, co napisaliśmy i ogólnej organizacji kodu. Natomiast JSHint, jak sama nazwa wskazuje, dostarcza uwagi skierowane już ściśle do naszego kodu JavaScript. Podczas pracy polecam korzystanie z obu tych narzędzi.

Dalej mamy dwa przyciski, które co prawda nie służą do bezpośredniej pracy, ale warto je poznać. Najpierw widzimy coś w rodzaju tablicy ogłoszeń o pracy. Oferty są naprawdę bardzo ciekawe z tym, że na razie jeszcze nie widziałem niestety żadnej z Polski. Ostatnim elementem jest możliwość zalogowania się.

Omówmy teraz lewą kolumnę strony, która to już skupia się na aspektach czysto technicznych tworzonego projektu. Pierwsza daje nam możliwość wybrania biblioteki jak i tego, w jaki sposób nasz skrypt na stronie zostanie umieszczony. My oczywiście wybieramy najnowszą wersję underscore.js. W moim przypadku będzie to wersja 1.4.4, a jeżeli chodzi o umieszczenie skryptu, to możemy pozostawić onLoad. W kolejnej może ustawić wartości opisujące to, co w danym momencie tworzymy. Następnie mamy zakładkę, która jest nieodzowna, jeżeli zamierzamy stworzyć coś nieco większego lub niestandardowego. Mówię tutaj o zakładce External Resources (materiały zewnętrzne). Możemy dzięki niej dodawać odnośniki do skryptów czy też styli, których potrzebujemy. Fakt, że jest to niesamowicie przydatne i nie wymaga raczej jakiegoś większego tłumaczenia.

Następna zakładka umożliwia nam dostosowanie rodzajów języków, jakich chcemy używać. Wybór nie jest jakiś przesadnie ogromny. Możemy wybierać z dwóch opcji, jeżeli chodzi o style i trzech, jeżeli o skrypty klienckie. Patrząc dalej widzimy zakładkę dotyczącą żądań AJAX-owych. Można znaleźć tutaj pełną dokumentację oraz przykłady, które pomogą nam opanować to zagadnienie. Przedostatnia już zakładka jest w całości poświęcona prezentowaniu przykładów zastosowań narzędzia, jakim jest jsfiddle. I jak niemal zawsze na końcu, dowiadujemy się, jaki jest status prawny narzędzia, z którego chcemy korzystać. 

Przejdźmy teraz do faktycznej nauki underscore.js. Na początku chciałbym zauważyć, że underscore.js to jedyna biblioteka, której stosowania nie będziemy się uczyć na mniejszych lub większych projektach. Wynika to z dwóch kwestii. Pierwszą z nich jest jej specyfika. Nie narzuca nam ona żadnej organizacji naszej aplikacji. Dostarcza jedynie zestaw metod, których powinniśmy używać w stosownych sytuacjach. Zupełnie jak wspomniany już LINQ. Drugą natomiast jest to, że bardzo zależy mi na zaprezentowaniu tego rozwiązania, ponieważ jest ono naprawdę wyjątkowo przydatne, jeżeli wiemy, kiedy i jak go używać. Podczas tworzenia jakiegoś konkretnego projektu wielu ciekawych metod nie udało by się pokazać lub po prostu gdzieś umknęłyby w kodzie.

W jaki sposób będzie wyglądało prezentowanie i omawianie kolejnych metod underscore.js? Otóż bardzo prosto. Na początku omówimy teoretycznie, do czego powinna być używana dana metoda. Potem zapiszemy kod ilustrujący jej możliwości i faktyczne działanie. Jak mówi stare chińskie przysłowie „Wiersz kodu objaśnia więcej niż tysiąc słów”. Na końcu, jeżeli nasz kod zadziała poprawnie, zobaczymy jego wyniki wypisane w konsoli narzędzia deweloperskiego. Okno przeglądarki, jeżeli oczywiście chcesz robić przykłady razem ze mną, powinno wyglądać jak na rysunku 2. Należy zwrócić uwagę na dwa kluczowe elementy: Czy underscore.js została dodana do naszego projektu oraz czy nasze narzędzie jest otwarte wraz z oknem konsoli.

rogowski2

Rysunek 2. Konfiguracja przeglądarki do nauki underscore.js

Skoro wszystko jest już jasne i skonfigurowane możemy wziąć się do poznawania underscore.js.

_.each(list, iterator)

Funkcja each jest używana w sytuacjach, w których mamy wykonać pewną operację na wszystkich elementach danej kolekcji. Pierwszym parametrem funkcji jest kolekcja elementów, na których będziemy wykonywać operację, rugim –funkcja definiująca, co ma być wykonane na wejściowych elementach.

Jako element wejściowy weźmiemy tablicę z obiektami zawierającymi dane o samochodach. Dla każdego obiektu wyświetlmy w konsoli odpowiednio sformatowane zdanie.

Listing 3. Użycie funkcji each

var cars = [{

name: ‘bmw,

cost: ‘10.000$’,

year: 2012

}, {

name: ‘audi’,

cost: ‘11.000$’,

year: 2013

}, {

name: ‘nissan’,

cost: ‘19.000$’,

year: 2010

}];

 

var showInfo = function (car) {

console.log(car.name + “ from “ + car.year + “ costs “ + car.cost);

};

 

_.each(cars, showInfo);

Najpierw jest definiowana kolekcja elementów wejściowych. Następnie przy użyciu funkcji showInfo na konsoli są wyświetlane informacje przekazane przez obiekt wejściowy. Ostatnią część kodu stanowi wywołanie metody each.

Rysunek 3. Wynik działania funkcji each

rogowski3

Na rysunku 3 widzimy, że dla każdego elementu przekazanego do funkcji showInfo otrzymaliśmy oddzielny wpis w konsoli. Za chwilę porównamy uzyskany wynik z wynikiem działania funkcji map, która w pewien sposób działa podobnie do funkcji each.

Podsumowanie

Było to wprowadzenie oraz początek pierwszego rozdziału książki „Świat poza jQuery... Wybrałem akurat tę część, ponieważ chciałem pokazać w jakim tonie będzie napisana przeze mnie książka.

Mam oczywiście nadzieję, że przynajmniej część z Was została zachęcona do zapoznania się z tą pozycją. Bez znaczenia jednak na to chciałbym bardzo podziękować osobom, które przeczytały ten fragment.

Jeżeli macie jakiekolwiek uwagi czy pytanie to można się ze mną kontaktować na karol.rogowski@gmail.com lub poprzez Twitter-a na @KarolRogowski.

Autor: Karol Rogowski

Polecamy

Partnerzy