Rafał Wrzeszcz - Wrzasq.pl

Przegląd frameworków JavaScript: Prototype

Saturday, 13 June 2009, 05:44

dojo
jQuery

Prototype

Jako ostatni przetestowałem bibliotekę Prototype. Swego czasu była to biblioteka najbardziej popularna w projektach korporacyjnych. Realizuje podobny model jak MooTools, jednak można przy jej pomocy tworzyć kod przypominający ten tworzony pod jQuery. Prototype to rozwiązanie dojrzałe i spójne. Mimo iż trochę brakuje niektórych aspektów, to pozostałe są dopracowane bardzo szczegółowo. Jedynym mankamentem tej biblioteki jest dramatycznie niska wydajność w przeglądarkach Internet Explorer (przynajmniej w kwestii obsługi selektorów, bo to właśnie obejmuje test SlickSpeed, na wynikach którego się opieram). W pozostałych przeglądarkach spokojnie może on konkurować z MooTools, czy jQuery, a nawet zazwyczaj je przeganiać - jedynie dojo pozostaje niedoścignionym demonem szybkości. Po przeglądzie wszystkich bibliotek to właśnie na Prototype postanowiłem postawić i wydaje mi się, że był to dobry wybór. Korzysta się z niego bardzo wygodnie, oferuje bardzo szeroką funkcjonalność przy minimalnym ograniczaniu już istniejącej funkcjonalności i pozostawiając szerokie możliwości rozbudowy. Tworzony kod jest bardzo wygodny i sami decydujemy w jakim stopniu używamy frameworku, a ile robimy standardowymi metodami.

Integracja z kodem

Wszystko odbywa się praktycznie przez załadowanie pojedynczego pliku biblioteki. Prototype rozszerza wiele podstawowych typów danych, więc nie trzeba przerabiać już istniejącego kodu JavaScript aby wykorzystać funkcjonalność dostarczaną przez tę bibliotekę. Dla niektórych niewygodne może być to, jak bardzo ingeruje on w globalną przestrzeń nazw tworząc w niej swoje obiekty, ale taka jest cena mechaniki, która nim rządzi - dla mnie nie jest to wada, a dzięki temu tworzony kod wygląda bardziej naturalnie (w rozumieniu kodu JavaScript ;)). Do najczęściej używanych poleceń dostępne są globalne aliasy typu $A() do przekształcania iterowalnych obiektów w rzeczywiste tablice, czy $H() do mapowania tablic asocjacyjnych.

Praca z drzewem DOM

Tutaj Prototype spisuje się wyśmienicie. Oczywiście możemy wyszukiwać elementy dzięki selektorom używając funkcji $(), która jest globalnym aliasem dla Element.getElementsBySelector(), oraz mamy krótki alias dla document.getElementById() pod postacią $(). Framework rozszerza natywne typy danych, dzięki temu pracując z drzewem DOM styl naszego kodu nie różni się zbyt wiele od tego, jaki tworzy się z wykorzystaniem standardowych metod udostępnianych przez przeglądarkę, poza tym, że jest to znacznie prostsze:

var element = $("masksList");
element.tBodies[0].deleteRow(-1); // to standardowa operacja
var links = element.getElementsBySelector("a.klasa"); // a to już funkcjonalność Prototype

Podobnie jak w przypadku MooTools używanie w tym wypadku funkcji $() jest potrzebne tylko po to, aby nasz kod zadziałał w przeglądarkach Internet Explorer w wersjach wcześniejszych niż IE8. Napisałem jednak na początku, że jeśli bardzo chcemy, możemy skonstruować kod wygodny nawet dla wielbicieli tasiemców rodem z jQuery:

// czyż to nie piękne…
$(this.caption).insert( new Element("a", {
    href: "/admin.php?action=" + list.browser + "&path=" + url
} ).update("/").observe("click", getTargetDirectorySwitcher(list.browser, list.path, "") ) );

Jednak moim zdaniem nawet tego typu kod z wykorzystaniem Prototype wygląda o wiele bardziej czytelnie niż w przypadku jQuery, gdzie praktycznie wszystko odbywało by się za naszymi plecami. Szkoda jedynie, że sama lista elementów nie jest w żaden sposób rozszerzana w pewne wyspecjalizowane metody typu filtrowanie, czy dołączanie następnych elementów.

Obsługa zdarzeń

Na tym polu chyba nie ma co odstawać od normy, tak jak w innych bibliotekach tego typu. Trochę niewygodny może być jedynie brak dedykowanych funkcji dla standardowych zdarzeń - wszystkie obsługujemy za pomocą Element.observe(). Funkcje obsługi zdarzeń, które tworzymy dostają jako argument naturalnie obiekt samego zdarzenia, co pozwala nam zatrzymać jego propagację, czy też domyślną akcję.

XHR/AJAX

Tutaj niestety jest trochę nieporęcznie. Niby wszystko jest w porządku, ale jednak metoda pracy z wywołaniami HTTP w tym frameworku jest utrudniona. Otóż metody obsługi naszego zapytania dostają jako argument cały wrapper zapytania - niezależnie od tego, czy pracujemy z formatem JSON, XML, czy jakimkolwiek innym. Oczywiście w zależności od formatu nasze dane są odpowiednio ładowane, ale sam fakt odwoływania się do dodatkowych pól obiektu jest dość niewygodny - nic nie stoi na przeszkodzie, żeby obiekt samego zapytania (jeśli ktoś będzie potrzebował) przekazywać jako drugi argument, a same dane jako pierwszy, gdyż zazwyczaj tylko to jest potrzebne i tak robią poprzednio opisywane przeze mnie biblioteki:

new Ajax.Request("/ajax.php", {
    parameters: {
        action: "CommentBlog",
        id: id
    },
    onSuccess: function(transport) {
        // nie jest to najwygodniejsze
        // szczególnie dla nieobeznanych
        displayFirstMessage(transport.responseJSON);
        
        var comments = transport.responseJSON.Comments;
        
        /* tutaj operacja na komentarzach */
    }
} );

Oczywiście nie jest to coś, co uniemożliwiło by pracę, ale jednak jest to odrobinę denerwujące.

Widgety i dodatki

Z samej podstawowej biblioteki Prototype z zakresu jakichkolwiek efektów wymienić można co najwyżej show() i hide(). Ale to dlatego, że podobnie jak MooTools, wszystko co odpowiedzialne za efekty wizualne i interfejs użytkownika zostało wydzielone do oddzielnej biblioteki - Scriptaculous. Na szczęście w przeciwieństwie do tej omawianej poprzednio, w tym wypadku mamy do dyspozycji bardzo rozbudowaną dokumentację z wieloma przykładami (a także chyba easter eggami :P).

Moja opinia

Prototype ma pewne niedociągnięcia co prawda, ale najbardziej przypadł mi do gustu spośród opisywanych przeze mnie frameworków. Przede wszystkim ze względu na założenia, które pokrywały się z moimi wymaganiami. Jest to rozwiązanie dojrzałe, nadające się do zastosowań na większą skalę, a to szczególnie dzięki integracji z natywnymi typami danych i nie próbowaniu na siłę obejść tego, czego i tak nie da się przeskoczyć.

Spośród opisywanych przeze mnie bibliotek na pierwszym miejscu postawiłbym dojo, szczególnie, jeśli komuś zależy na wydajności i efektowności wykonywanych prac. Jeśli natomiast liczy się kod i wygoda pracy, to moim zdaniem najodpowiedniejszy jest właśnie Prototype. MooTools to rozwiązanie pośrednie - zrealizowane w sposób podobny jak Prototype, ale jednak idące w kierunku zbliżonym, do jQuery, co po pierwsze mi nie odpowiada, a po drugie powoduje pewne niekonsekwencje. Niemniej ta ostatnia to według mnie najsłabszy element tego zestawienia, co jest nieco zaskakujące po tym, jakie poruszenie za jej sprawą zauważyłem w sieci. Jednak każda z nich ma swoje wady, zalety i narzuca dość specyficzny styl tworzenia aplikacji, przez co każdemu może pasować coś innego.

Tags: Web, Teksty, JavaScript, AJAX, DOM