Javascript. Wzorce

Twórz lepszy kod JavaScript! Jakie jest najlepsze podejście do tworzenia aplikacji w języku JavaScript? Z tą książką, za

915 114 3MB

Polish Pages [193] Year 2012

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Javascript. Wzorce

Table of contents :
Spis treści
Wstęp
1. Wprowadzenie
Wzorce
JavaScript — podstawowe cechy
Zorientowany obiektowo
Brak klas
Prototypy
Środowisko
ECMAScript 5
Narzędzie JSLint
Konsola
2. Podstawy
Tworzenie kodu łatwego w konserwacji
Minimalizacja liczby zmiennych globalnych
Problem ze zmiennymi globalnymi
Efekty uboczne pominięcia var
Dostęp do obiektu globalnego
Wzorzec pojedynczego var
Przenoszenie deklaracji — problem rozrzuconych deklaracji var
Pętle for
Pętle for-in
Modyfikacja wbudowanych prototypów
Wzorzec konstrukcji switch
Unikanie niejawnego rzutowania
Unikanie eval()
Konwertowanie liczb funkcją parseInt()
Konwencje dotyczące kodu
Wcięcia
Nawiasy klamrowe
Położenie nawiasu otwierającego
Białe spacje
Konwencje nazewnictwa
Konstruktory pisane od wielkiej litery
Oddzielanie wyrazów
Inne wzorce nazewnictwa
Pisanie komentarzy
Pisanie dokumentacji interfejsów programistycznych
Przykład dokumentacji YUIDoc
Pisanie w sposób ułatwiający czytanie
Ocenianie kodu przez innych członków zespołu
Minifikowanie kodu tylko w systemie produkcyjnym
Uruchamiaj narzędzie JSLint
Podsumowanie
3. Literały i konstruktory
Literał obiektu
Składnia literału obiektowego
Obiekty z konstruktora
Pułapka konstruktora Object
Własne funkcje konstruujące
Wartość zwracana przez konstruktor
Wzorce wymuszania użycia new
Konwencja nazewnictwa
Użycie that
Samowywołujący się konstruktor
Literał tablicy
Składnia literału tablicy
Pułapka konstruktora Array
Sprawdzanie, czy obiekt jest tablicą
JSON
Korzystanie z formatu JSON
Literał wyrażenia regularnego
Składnia literałowego wyrażenia regularnego
Otoczki typów prostych
Obiekty błędów
Podsumowanie
Informacje ogólne
4. Funkcje
Informacje ogólne
Stosowana terminologia
Deklaracje kontra wyrażenia — nazwy i przenoszenie na początek
Właściwość name funkcji
Przenoszenie deklaracji funkcji
Wzorzec wywołania zwrotnego
Przykład wywołania zwrotnego
Wywołania zwrotne a zakres zmiennych
Funkcje obsługi zdarzeń asynchronicznych
Funkcje czasowe
Wywołania zwrotne w bibliotekach
Zwracanie funkcji
Samodefiniujące się funkcje
Funkcje natychmiastowe
Parametry funkcji natychmiastowych
Wartości zwracane przez funkcje natychmiastowe
Zalety i zastosowanie
Natychmiastowa inicjalizacja obiektu
Usuwanie warunkowych wersji kodu
Właściwości funkcji — wzorzec zapamiętywania
Obiekty konfiguracyjne
Rozwijanie funkcji
Aplikacja funkcji
Aplikacja częściowa
Rozwijanie funkcji
Kiedy używać aplikacji częściowej
Podsumowanie
5. Wzorce tworzenia obiektów
Wzorzec przestrzeni nazw
Funkcja przestrzeni nazw ogólnego stosowania
Deklarowanie zależności
Metody i właściwości prywatne
Składowe prywatne
Metody uprzywilejowane
Problemy z prywatnością
Literały obiektów a prywatność
Prototypy a prywatność
Udostępnianie funkcji prywatnych jako metod publicznych
Wzorzec modułu
Odkrywczy wzorzec modułu
Moduły, które tworzą konstruktory
Import zmiennych globalnych do modułu
Wzorzec piaskownicy
Globalny konstruktor
Dodawanie modułów
Implementacja konstruktora
Składowe statyczne
Publiczne składowe statyczne
Prywatne składowe statyczne
Stałe obiektów
Wzorzec łańcucha wywołań
Wady i zalety wzorca łańcucha wywołań
Metoda method()
Podsumowanie
6. Wzorce wielokrotnego użycia kodu
Klasyczne i nowoczesne wzorce dziedziczenia
Oczekiwane wyniki w przypadku stosowania wzorca klasycznego
Pierwszy wzorzec klasyczny — wzorzec domyślny
Podążanie wzdłuż łańcucha prototypów
Wady wzorca numer jeden
Drugi wzorzec klasyczny — pożyczanie konstruktora
Łańcuch prototypów
Dziedziczenie wielobazowe przy użyciu pożyczania konstruktorów
Zalety i wady wzorca pożyczania konstruktora
Trzeci wzorzec klasyczny — pożyczanie i ustawianie prototypu
Czwarty wzorzec klasyczny — współdzielenie prototypu
Piąty wzorzec klasyczny — konstruktor tymczasowy
Zapamiętywanie klasy nadrzędnej
Czyszczenie referencji na konstruktor
Podejście klasowe
Dziedziczenie prototypowe
Dyskusja
Dodatki do standardu ECMAScript 5
Dziedziczenie przez kopiowanie właściwości
Wzorzec wmieszania
Pożyczanie metod
Przykład — pożyczenie metody od obiektu Array
Pożyczenie i przypisanie
Metoda Function.prototype.bind()
Podsumowanie
7. Wzorce projektowe
Singleton
Użycie słowa kluczowego new
Instancja we właściwości statycznej
Instancja w domknięciu
Fabryka
Wbudowane fabryki obiektów
Iterator
Dekorator
Sposób użycia
Implementacja
Implementacja wykorzystująca listę
Strategia
Przykład walidacji danych
Fasada
Pośrednik
Przykład
Pośrednik jako pamięć podręczna
Mediator
Przykład mediatora
Obserwator
Pierwszy przykład — subskrypcja magazynu
Drugi przykład — gra w naciskanie klawiszy
Podsumowanie
8. DOM i wzorce dotyczące przeglądarek
Podział zadań
Skrypty wykorzystujące DOM
Dostęp do DOM
Modyfikacja DOM
Zdarzenia
Obsługa zdarzeń
Delegacja zdarzeń
Długo działające skrypty
Funkcja setTimeout()
Skrypty obliczeniowe
Komunikacja z serwerem
Obiekt XMLHttpRequest
JSONP
Ramki i wywołania jako obrazy
Serwowanie kodu JavaScript klientom
Łączenie skryptów
Minifikacja i kompresja
Nagłówek Expires
Wykorzystanie CDN
Strategie wczytywania skryptów
Lokalizacja elementu
Wysyłanie pliku HTML fragmentami
Dynamiczne elementy zapewniające nieblokujące pobieranie
Wczytywanie leniwe
Wczytywanie na żądanie
Wstępne wczytywanie kodu JavaScript
Podsumowanie
Skorowidz

Citation preview

Spis treści

Wstęp ............................................................................................................................11 1. Wprowadzenie ............................................................................................................ 15 Wzorce JavaScript — podstawowe cechy Zorientowany obiektowo Brak klas Prototypy Środowisko ECMAScript 5 Narzędzie JSLint Konsola

15 16 16 17 18 18 18 19 20

2. Podstawy ..................................................................................................................... 21 Tworzenie kodu łatwego w konserwacji Minimalizacja liczby zmiennych globalnych Problem ze zmiennymi globalnymi Efekty uboczne pominięcia var Dostęp do obiektu globalnego Wzorzec pojedynczego var Przenoszenie deklaracji — problem rozrzuconych deklaracji var Pętle for Pętle for-in Modyfikacja wbudowanych prototypów Wzorzec konstrukcji switch Unikanie niejawnego rzutowania Unikanie eval() Konwertowanie liczb funkcją parseInt()

21 22 22 24 25 25 26 27 29 31 31 32 32 34

5

Konwencje dotyczące kodu Wcięcia Nawiasy klamrowe Położenie nawiasu otwierającego Białe spacje Konwencje nazewnictwa Konstruktory pisane od wielkiej litery Oddzielanie wyrazów Inne wzorce nazewnictwa Pisanie komentarzy Pisanie dokumentacji interfejsów programistycznych Przykład dokumentacji YUIDoc Pisanie w sposób ułatwiający czytanie Ocenianie kodu przez innych członków zespołu Minifikowanie kodu tylko w systemie produkcyjnym Uruchamiaj narzędzie JSLint Podsumowanie

34 35 35 36 37 38 38 39 39 40 41 42 44 45 46 47 47

3. Literały i konstruktory .................................................................................................49 Literał obiektu Składnia literału obiektowego Obiekty z konstruktora Pułapka konstruktora Object Własne funkcje konstruujące Wartość zwracana przez konstruktor Wzorce wymuszania użycia new Konwencja nazewnictwa Użycie that Samowywołujący się konstruktor Literał tablicy Składnia literału tablicy Pułapka konstruktora Array Sprawdzanie, czy obiekt jest tablicą JSON Korzystanie z formatu JSON Literał wyrażenia regularnego Składnia literałowego wyrażenia regularnego Otoczki typów prostych Obiekty błędów Podsumowanie

6

|

Spis treści

49 50 51 51 52 53 54 54 54 55 56 56 56 57 58 58 59 60 61 62 63

4. Funkcje .........................................................................................................................65 Informacje ogólne Stosowana terminologia Deklaracje kontra wyrażenia — nazwy i przenoszenie na początek Właściwość name funkcji Przenoszenie deklaracji funkcji Wzorzec wywołania zwrotnego Przykład wywołania zwrotnego Wywołania zwrotne a zakres zmiennych Funkcje obsługi zdarzeń asynchronicznych Funkcje czasowe Wywołania zwrotne w bibliotekach Zwracanie funkcji Samodefiniujące się funkcje Funkcje natychmiastowe Parametry funkcji natychmiastowych Wartości zwracane przez funkcje natychmiastowe Zalety i zastosowanie Natychmiastowa inicjalizacja obiektu Usuwanie warunkowych wersji kodu Właściwości funkcji — wzorzec zapamiętywania Obiekty konfiguracyjne Rozwijanie funkcji Aplikacja funkcji Aplikacja częściowa Rozwijanie funkcji Kiedy używać aplikacji częściowej Podsumowanie

65 66 67 68 68 70 70 72 73 73 74 74 75 76 77 77 79 79 80 82 83 84 84 85 87 89 89

5. Wzorce tworzenia obiektów ...................................................................................... 91 Wzorzec przestrzeni nazw Funkcja przestrzeni nazw ogólnego stosowania Deklarowanie zależności Metody i właściwości prywatne Składowe prywatne Metody uprzywilejowane Problemy z prywatnością Literały obiektów a prywatność Prototypy a prywatność Udostępnianie funkcji prywatnych jako metod publicznych

91 92 94 95 96 96 96 98 98 99

Spis treści

|

7

Wzorzec modułu Odkrywczy wzorzec modułu Moduły, które tworzą konstruktory Import zmiennych globalnych do modułu Wzorzec piaskownicy Globalny konstruktor Dodawanie modułów Implementacja konstruktora Składowe statyczne Publiczne składowe statyczne Prywatne składowe statyczne Stałe obiektów Wzorzec łańcucha wywołań Wady i zalety wzorca łańcucha wywołań Metoda method() Podsumowanie

100 102 102 103 103 104 105 106 107 107 109 110 112 112 113 114

6. Wzorce wielokrotnego użycia kodu ..........................................................................115 Klasyczne i nowoczesne wzorce dziedziczenia Oczekiwane wyniki w przypadku stosowania wzorca klasycznego Pierwszy wzorzec klasyczny — wzorzec domyślny Podążanie wzdłuż łańcucha prototypów Wady wzorca numer jeden Drugi wzorzec klasyczny — pożyczanie konstruktora Łańcuch prototypów Dziedziczenie wielobazowe przy użyciu pożyczania konstruktorów Zalety i wady wzorca pożyczania konstruktora Trzeci wzorzec klasyczny — pożyczanie i ustawianie prototypu Czwarty wzorzec klasyczny — współdzielenie prototypu Piąty wzorzec klasyczny — konstruktor tymczasowy Zapamiętywanie klasy nadrzędnej Czyszczenie referencji na konstruktor Podejście klasowe Dziedziczenie prototypowe Dyskusja Dodatki do standardu ECMAScript 5 Dziedziczenie przez kopiowanie właściwości Wzorzec wmieszania Pożyczanie metod Przykład — pożyczenie metody od obiektu Array Pożyczenie i przypisanie Metoda Function.prototype.bind() Podsumowanie 8

|

Spis treści

115 116 117 117 119 119 120 121 122 122 123 124 125 125 126 129 129 130 131 132 133 134 134 135 136

7. Wzorce projektowe ....................................................................................................137 Singleton Użycie słowa kluczowego new Instancja we właściwości statycznej Instancja w domknięciu Fabryka Wbudowane fabryki obiektów Iterator Dekorator Sposób użycia Implementacja Implementacja wykorzystująca listę Strategia Przykład walidacji danych Fasada Pośrednik Przykład Pośrednik jako pamięć podręczna Mediator Przykład mediatora Obserwator Pierwszy przykład — subskrypcja magazynu Drugi przykład — gra w naciskanie klawiszy Podsumowanie

137 138 139 139 141 143 143 145 145 146 148 149 150 152 153 153 159 160 160 163 163 166 169

8. DOM i wzorce dotyczące przeglądarek ..................................................................... 171 Podział zadań Skrypty wykorzystujące DOM Dostęp do DOM Modyfikacja DOM Zdarzenia Obsługa zdarzeń Delegacja zdarzeń Długo działające skrypty Funkcja setTimeout() Skrypty obliczeniowe Komunikacja z serwerem Obiekt XMLHttpRequest JSONP Ramki i wywołania jako obrazy

171 172 173 174 175 175 177 178 178 179 179 180 181 184

Spis treści

|

9

Serwowanie kodu JavaScript klientom Łączenie skryptów Minifikacja i kompresja Nagłówek Expires Wykorzystanie CDN Strategie wczytywania skryptów Lokalizacja elementu // drugie rozwiązanie

Istnieje jednak kilka wzorców oraz sztuczek, o których warto pamiętać, jeśli celem jest tworzenie wysoce wydajnych aplikacji. Oto kilka typowych atrybutów stosowanych przez większość programistów wraz z elementem



...

Lepszym rozwiązaniem jest połączenie wszystkich plików w jeden.

Moja aplikacja

...

Jeszcze lepsze jest umieszczenie połączonych skryptów na samym końcu strony.

Moja aplikacja

...



Strategie wczytywania skryptów

|

187

Wysyłanie pliku HTML fragmentami Protokół HTTP obsługuje przesyłanie plików fragmentami bez podawania ich pełnej długości. Jeśli więc istnieje pewna złożona strona WWW, nie trzeba czekać na wykonanie wszystkich działań serwerowych przed rozpoczęciem wysyłania wyniku do klienta, szczególnie jeśli początkowa część strony (nagłówek) jest niezmienna. Najprostsza strategia polega na wysłaniu części dokumentu w pierwszym pakiecie, a pozostałej części dopiero po zebraniu przez serwer wszystkich niezbędnych informacji. Innymi słowy, wysłany zostanie kod:

Moja aplikacja

Prostym usprawnieniem byłoby przeniesienie kodu JavaScript z powrotem do części nagłówkowej, bo w ten sposób przeglądarka rozpoczęłaby pobieranie skryptów, zanim jeszcze otrzymałaby właściwą część strony.

Moja aplikacja



Jeszcze lepsze byłoby zastosowanie trzech fragmentów. Ostatni z nich zawierałby tylko i wyłącznie informację o skrypcie. Dodatkowo w pierwszym fragmencie warto byłoby wysłać statyczny nagłówek (na przykład logo) znajdujący się na każdej stronie WWW witryny.

Moja aplikacja



...







Prawie we wszystkich aplikacjach leniwa część kodu jest większa niż część podstawowa, ponieważ interesujące działania takie jak przenoszenie elementów, użycie XHR i odtwarzanie animacji zazwyczaj wykonuje się dopiero po akcji użytkownika.

Wczytywanie na żądanie Poprzedni wzorzec wczytywał dodatkowy kod JavaScript bezwarunkowo po załadowaniu strony WWW, zakładając, że kod ten będzie najprawdopodobniej potrzebny. Czy nie można jednak zrobić lepiej? W wielu sytuacjach nic nie stoi na przeszkodzie, by wczytywać fragmenty kodu tylko wtedy, gdy są naprawdę potrzebne. Wyobraźmy sobie pasek boczny z kilkoma zakładkami. Kliknięcie zakładki powoduje wysłanie żądania XHR, by pobrać nową zawartość i zaanimować zmianę danych po uzyskaniu odpowiedzi. Załóżmy, że zakładki to jedyne miejsce stosujące żądanie XHR i animacje. Czy naprawdę trzeba pobierać ten kod, jeśli użytkownik nigdy nie przełączy zakładek? Najwyższy czas na wzorzec wczytywania na żądanie. Można utworzyć funkcję require(), która będzie przyjmowała nazwę pliku do wczytania, i funkcję wywołania zwrotnego, która zostanie uruchomiona po wczytaniu skryptu. Oto przykład użycia wspomnianej funkcji require(): require("extra.js", function () { functionDefinedInExtraJS(); });

Jak można taką funkcję zaimplementować? Żądanie pobrania i wykonania dodatkowego kodu nie stanowi problemu — to dobrze znany wzorzec dynamicznego umieszczania elementu . Określenie momentu wczytania skryptu jest nieco bardziej złożone, głównie ze względu na różnice między przeglądarkami. function require(file, callback) { var script = document.getElementsByTagName('script')[0], newjs = document.createElement('script'); // IE newjs.onreadystatechange = function () { if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') { newjs.onreadystatechange = null; callback();

Strategie wczytywania skryptów

|

191

} }; // inne newjs.onload = function () { callback(); }; newjs.src = file; script.parentNode.insertBefore(newjs, script); }

Kilka komentarzy na temat implementacji: • W IE trzeba zarejestrować się jako odbiorca zdarzenia readystatechange, a następnie

sprawdzać istnienie tekstów "loaded" lub "complete" we właściwości readyState. Wszystkie inne przeglądarki pominą ten kod. • W przeglądarkach Firefox, Safari, Chrome i Opera zarejestrowanie się jako odbiorca do-

tyczy zdarzenia load (właściwość onload). • Przedstawione rozwiązania nie zadziałają poprawnie dla przeglądarki Safari 2. Jeśli jej

obsługa jest niezbędna, trzeba okresowo sprawdzać, czy została zdefiniowana określona zmienna (ustawiana przez wczytywany kod). Jej ustawienie oznacza, że nowy skrypt został wczytany poprawnie. Implementację można przetestować, stosując skrypt ze sztucznym opóźnieniem (symulujący długie pobieranie zawartości) i nazwie ondemandjs.php.

function extraFunction(logthis) { console.log('wczytane i wykonane'); console.log(logthis); }

Oto krótki test funkcji require(): require('ondemand.js.php', function () { extraFunction('wczytane ze strony głównej'); document.body.appendChild(document.createTextNode('koniec!')); });

Przedstawione fragmenty kodu spowodują wyświetlenie w konsoli dwóch wierszy tekstu i umieszczenie na stronie tekstu „koniec!”. W pełni działający przykład jest dostępny pod adresem http://www.jspatterns.com/book/8/ondemand.html.

Wstępne wczytywanie kodu JavaScript Wcześniejsze wzorce starały się opóźnić wczytywanie kodu, którego wykonanie było niezbędne na aktualnej stronie. Czasem warto również w trakcie korzystania przez użytkownika z bieżącej strony wczytać kod, który będzie najprawdopodobniej potrzebny na stronie następnej. Gdy użytkownik zdecyduje się odwiedzić drugą stronę, dotyczący jej kod będzie już znajdował się w pamięci przeglądarki, więc uzyska się wrażenie znacznie szybszego działania witryny.

192

|

Rozdział 8. DOM i wzorce dotyczące przeglądarek

Wczytywanie wstępne można zaimplementować za pomocą wzorca skryptów dynamicznych. Oznacza to jednak, że skrypt zostanie przeanalizowany i wykonany. Analiza to najczęściej jedynie ułamek czasu spędzonego na pobieraniu skryptu, ale wykonanie go może spowodować pojawienie się błędów (bo kod będzie zakładał jego uruchomienie na drugiej stronie). Możliwe jest pobranie skryptów do pamięci podręcznej przeglądarki bez ich wykonywania. Podobna sztuczka działa również z plikami CSS i obrazami. W IE zadanie jest bardzo proste i polega na użyciu znanego już wybiegu ze wzorcem logowania danych na serwerze. new Image().src = "preloadme.js";

We wszystkich innych przeglądarkach niezbędne jest użycie zamiast elementu skryptu elementu i ustawienie jego atrybutu data na adres URL skryptu. var obj = document.createElement('object'); obj.data = "preloadme.js"; document.body.appendChild(obj);

Aby obiekt nie był widoczny na stronie, warto ustawić jego szerokość (atrybut width) i wysokość (atrybut height) na 0. Stosunkowo łatwo utworzyć ogólną funkcję preload(), a także wykorzystać wzorzec usuwania niepotrzebnego kodu (rozdział 4.), by obsłużyć różnice między przeglądarkami. var preload; if (/*@cc_on!@*/false) { // wykrywanie IE za pomocą komentarzy warunkowych preload = function (file) { new Image().src = file; }; } else { preload = function (file) { var obj = document.createElement('object'), body = document.body; obj.width = 0; obj.height = 0; obj.data = file; body.appendChild(obj); }; }

Wykorzystanie nowej funkcji jest bardzo proste: preload("my_web_worker.js");

Wadą przedstawionego rozwiązania jest istnienie wykrywania agenta użytkownika, ale niestety nie można tego uniknąć, bo zwykłe wykrywanie możliwości niewiele w tej sytuacji pomoże. W teorii można by sprawdzić, czy Image jest funkcją (typeof Image == "function" ). Niestety, wszystkie przeglądarki obsługują new Image() , ale część z nich stosuje specjalne bufory dla obrazków, więc próba wczytania za pomocą takiego obiektu czegoś, co obrazem nie jest (czyli skryptu), nie zadziała zgodnie z oczekiwaniami i spowoduje ponowne pobranie pliku.

Strategie wczytywania skryptów

|

193

Wykrywanie rodzaju przeglądarki za pomocą komentarzy warunkowych to bardzo interesująca technika. Jest bezpieczniejsza od sprawdzania tekstu navigator.userAgent, bo ten użytkownik może dowolnie zmienić. Zapis var isIE = /*@cc_on!@*/false;

spowoduje ustawienie isIE na wartość false we wszystkich przeglądarkach (bo zignorują one komentarz) poza IE, która przypisze wartość true ze względu na negację zastosowaną w komentarzu warunkowym. Innymi słowy, IE wykona następujący kod: var isIE = !false;

Wzorzec wczytywania wstępnego można zastosować dla różnych komponentów, nie tylko dla skryptów. Przykładem może być strona logowania. Gdy użytkownik rozpoczyna wpisywanie swojego imienia i nazwiska, można rozpocząć wstępne wczytywanie dodatkowych danych dla następnej strony (oczywiście poza danymi uzależnionymi od użytkownika), bo jest wielce prawdopodobne, że za chwilę będzie ona stroną bieżącą.

Podsumowanie Podczas gdy poprzednie rozdziały książki dotyczyły przede wszystkim podstawowych wzorców języka JavaScript niezależnych od środowiska uruchomieniowego, w niniejszym rozdziale skupiliśmy się na wzorcach związanych tylko i wyłącznie z przeglądarkami internetowymi. Poruszane były następujące tematy: • Właściwy podział zadań (HTML — treść, CSS — prezentacja, JavaScript — zachowanie),

zastosowanie języka JavaScript jako rozszerzenia funkcjonalności i wykrywanie możliwości zamiast wersji przeglądarki (choć pod koniec rozdziału pojawiła się sytuacja wymagająca złamania tego wzorca).

• Kod używający DOM, czyli wzorce pozwalające przyspieszyć uzyskiwanie dostępu i wpro-

wadzanie modyfikacji do DOM głównie przez grupowanie zadań, gdyż każdy dostęp do DOM jest kosztowny.

• Zdarzenia, obsługiwanie ich w uniwersalny sposób i wykorzystanie delegacji zdarzeń do

redukcji liczby przypisywanych funkcji obsługi zdarzeń i poprawy wydajności.

• Dwa wzorce pomagające radzić sobie z długimi i kosztownymi obliczeniami: wykorzy-

stanie setTimeout() do podziału obliczeń na mniejsze fragmenty i użycie w nowoczesnych przeglądarkach dodatkowych wątków obliczeniowych.

• Różne wzorce komunikacji z serwerem bez ponownego wczytywania strony — XHR,

JSONP, ramki i obrazki.

• Kroki niezbędne do prawidłowego wdrożenia języka JavaScript w środowisku produk-

cyjnym — upewnianie się, że skrypty są łączone ze sobą (mniej plików do pobrania), minifikowane i kompresowane (oszczędność do 85%), a w sytuacji idealnej również umieszczane na serwerze CDN i przesyłane z nagłówkami Expires.

• Wzorce umieszczania skryptów na stronie internetowej w sposób zapewniający jak naj-

lepszą wydajność: różne techniki umieszczania elementu , wykorzystanie przesyłania stron WWW fragmentami, a także ograniczenie wpływu dużych skryptów na ogólny czas wczytywania strony przez wczytywanie leniwe, wstępne i na żądanie.

194

|

Rozdział 8. DOM i wzorce dotyczące przeglądarek

Skorowidz

.htaccess, 185 @class, 43 @method, 43 @namespace, 43 @param, 41, 43 @return, 41, 43 , 186, 187 dodawanie elementu, 190 dynamiczne elementy, 189 lokalizacja, 187

A addEventListener(), 175 alert(), 20 antywzorce, 16 Apache, .htaccess, 185 aplikacja częściowa, 85, 86, 89 funkcji, 84, 85 internetowa, 171 apply(), 85, 133, 134 arguments.callee, 55, 83 Array, 56, 57 asynchroniczne, zdarzenia, 73 atrybut, 17 attachEvent(), 175

B bąbelkowanie zdarzeń, 177 bind(), 135, 136 break, 32

C call(), 133, 134 case, 32 CDN, 186 Closure Compiler, 46, 80 console, obiekt, 20

constructor, właściwość, 18, 126 Content Delivery Network, Patrz CDN Crockford, Douglas, 19, 113 Curry, Haskell, 87 currying, Patrz funkcje, rozwijanie

D default, 32 dekoratora, wzorzec, 145, 169 implementacja, 146, 147, 148, 149 delegacje zdarzeń, wzorzec, 177 delete, operator, 24 dir(), 20 Document Object Model, Patrz DOM dodatki syntaktyczne, 113 dokumentacja, 41 JSDoc, 41 YUIDoc, 41, 42, 44 DOM, 172 dostęp, 173 modyfikacja, 174 dorozumiane zmienne globalne, 23, 24 dziedziczenie, 18, 136 klasyczne, 115, 116, 126 nowoczesne, 115, 116 prototypowe, 129, 130 przez kopiowanie właściwości, 131, 132 wielobazowe, 121

E ECMAScript 5, 18, 19 dodatki, 130 Error(), 62 ES5, Patrz ECMAScript 5 eval(), 19 unikanie, 32, 33 Expires, nagłówek, 185 extend(), 97, 132 extendDeep(), 97

195

F fabryki, wzorzec, 141, 142, 143, 169 fasady, wzorzec, 152, 153, 169 Firebug, 132 for, pętla, 27, 28 for-in, pętla, 29 Function(), 33, 66 Function.prototype.apply(), 84 funkcje, 17, 65, 66 anonimowe, 66, 68 czasowe, 73 deklaracje, 67, 68 konstruujące, 51, 52 name, właściwość, 68 natychmiastowe, 76, 77, 78, 79, 89 obsługi zdarzeń asynchronicznych, 73 pośredniczące, 126 prywatne, 99 rozwijanie, 84, 86, 87, 89 samodefiniujące się, 75, 76, 90 samowywołujące się, 79 terminologia, 66 właściwości, 82 wywołania zwrotnego, 70 wywołanie, 85 zwracanie, 74, 89

G globalne zmienne, 22, 23, 24 dorozumiane, 23, 24 gospodarza, obiekty, 17, 18

H hasOwnProperty(), 29, 30 hoisting, Patrz przenoszenie deklaracji HTML, wysyłanie pliku fragmentami, 188, 189 HTMLCollection, 27, 28

I inicjalizacja, 25 leniwa, 153 init(), 79, 80 instanceof, operator, 108 instancja, 115 isArray(), 57 iteratora, wzorzec, 143, 144, 169

196

|

Skorowidz

J JavaScript, 15 biblioteki, 94 jako język obiektowy, 16 sprawdzanie jakości kodu, 19 środowisko uruchomieniowe, 18 JavaScript Object Notation, Patrz JSON jQuery, biblioteka, 59, 132 JSDoc, 41 JSLint, 19, 47 JSON, 58 JSON with Padding, Patrz JSONP JSON.parse(), 58, 59 JSON.stringify(), 59 JSONP, 181, 182, 183

K klasy, 17, 126 emulacja, 126, 127 kod konwencje, 34, 35, 36, 37, 38 łatwy w konserwacji, 21, 22 minifikowanie, 46 ocenianie przez innych, 45, 46 usuwanie warunkowych wersji, 80, 81, 90 wielokrotne użycie, 115 kodowania, wzorce, 16 komentarze, 40, 41 kompresja, 185 konsola, 20 konstruktory, 54, 119 czyszczenie referencji, 125 pośredniczące, 126 pożyczanie, 119, 121, 122 samowywołujące, 55 tymczasowe, 124, 126 wartość zwracana, 53 konwencje kodu, 34, 35 białe spacje, 37, 38 nawias otwierający, 36, 37 nawiasy klamrowe, 35, 36 nazewnictwo, 38, 39, 40, 54 średniki, 37 wcięcia, 35 konwersja liczb, 34 kopia głęboka, 131 płytka, 131

L leniwa inicjalizacja, 153 leniwe wczytywanie, 190, 191 liczby, konwersja, 34 literały funkcji, 67 obiektów, 49, 50, 51, 98 tablicy, 56 wyrażenia regularnego, 59, 60 log(), 20 lokalne zmienne, 22

konfiguracyjne, 83, 84, 89 natychmiastowa inicjalizacja, 79, 90 rdzenne, 17 tworzenie, 51, 91 Object(), 18, 51, 143 Object.create(), 130 Object.prototype.toString(), 58 obserwator, 163 obserwatora, wzorzec, 163, 166, 169 obsługa zdarzeń, 175, 176 asynchronicznych, 73 onclick, atrybut, 175 open(), 180

Ł łańcuchy wywołań, 112

M Martin, Robert, 112 mediator, 160 mediatora, wzorzec, 160, 169 przykład, 160, 161, 162 uczestnicy, 160 method(), 113 metody, 17, 49 pożyczanie, 133, 134 prywatne, 95, 96 publiczne, 99 statyczne, 107, 108 uprzywilejowane, 96 minifikacja, 46, 185 moduły, 100, 101, 102 import zmiennych globalnych, 103 tworzące konstruktory, 102

N najmniejszego przywileju, zasada, 97 name, właściwość, 68 natychmiastowa inicjalizacja obiektu, 79, 90 nazewnictwo, konwencje, 38, 39, 40, 54 nazwane wyrażenie funkcyjne, 66, 67 new, słowo kluczowe, 54, 138 nienazwane wyrażenie funkcyjne, 66, 68 notacja literału obiektu, 49, 50, 51

P parseInt(), 34 parseJSON(), 59 pętle for, 27, 28 for-in, 29 piaskownicy, wzorzec, 103, 104, 105, 114 dodawanie modułów, 105 globalny konstruktor, 104 implementacja konstruktora, 106 pośrednika, wzorzec, 153, 155, 158, 159, 169 preventDefault(), 152 projektowe, wzorce, 16 prototype, właściwość, 18, 98 modyfikacja, 31 prototypy, 18 łańcuch, 117, 118, 120, 121 modyfikacja, 31 prywatność, 98 współdzielenie, 123, 124 prywatność, problemy, 96 przeglądarki, wykrywanie, 194 przenoszenie deklaracji, 26, 27 przestrzenie nazw, 22, 91, 92, 114 Firebug, 94

R ramki, 184 rdzenne obiekty, 17 RegExp(), 59, 60 rzutowanie niejawne, 32

O obiekty, 17, 51 błędów, 62 globalne, 22, 25 gospodarza, 17, 18

S Schönfinkel, Moses, 87 schönfinkelizacja, 87 send(), 180

Skorowidz

|

197

serializacja, 82, 83 serwer, komunikacja, 179 setInterval(), 33, 73 setTimeout(), 33, 73, 178 singleton, 137, 138, 169 składowe prywatne, 96 statyczne, 107, 109 skrypty łączenie, 184, 185 obliczeniowe, 179 strategie wczytywania, 186 stałe, 110, 111 stopPropagation(), 152 strategii, wzorzec, 149, 169 strict mode, Patrz tryb ścisły String.prototype.replace(), 60 styl wielbłądzi, 39 subskrybenta-dostawcy, wzorzec, 163, 169 supermetody, 152 switch, 31, 32 SyntaxError(), 62

Ś środowisko uruchomieniowe, 18

T that, 54, 55 this, 22, 53 throw, instrukcja, 62 tryb ścisły, 19 TypeError(), 62 typeof, 32, 57 typy proste, otoczki, 61, 62

V var, 23 efekty uboczne pominięcia, 24 problem rozrzuconych deklaracji, 26 wzorzec pojedynczego użycia, 25

W walidacja danych, 150 wątki, symulacja, 178 wczytywanie leniwe, 190, 191 na żądanie, 191 wstępne, 192, 193, 194

198

|

Skorowidz

wielbłądzi, styl, 39 window, właściwość, 22, 25 with, polecenie, 19 właściwości, 17, 49 prywatne, 95, 96 statyczne, 107, 110 wydajność, 184 wyliczenie, 29 wyrażenia regularne, 59 wyrażenie funkcyjne, 66, 67 nazwane, 66, 67 nienazwane, 66 wywołanie funkcji, 85 wywołanie jako obraz, 184 wywołanie zwrotne, 70, 71, 89 w bibliotekach, 74 zakres zmiennych, 72 wzorce, 11, 15 antywzorce, 16 API, 89 inicjalizacyjne, 89 kodowania, 16 optymalizacyjne, 90 projektowe, 16

X XHR, Patrz XMLHttpRequest XMLHttpRequest, 180, 181

Y Y.clone(), 132 Y.delegate(), 178 Yahoo! Query Language, Patrz YQL YQL, 157 YUI3, 132, 178 YUIDoc, 41, 42, 44 przykład dokumentacji, 42, 44

Z zdarzenia, 175 asynchroniczne, 73 delegacje, 177 obsługa, 175, 176 własne, 163 zmienne, 17 globalne, 22, 23, 24, 103 lokalne, 22