Wykład - Jezyki interpretowane
Transkrypt
Wykład - Jezyki interpretowane
Języki interpretowane dr inż. Andrzej Grosser Rok akademicki 2015/16 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 1 / 228 Plan wykładów I 1 Wprowadzenie do języków skryptowych 2 JavaScript - składnia, bibliotek standardowa 3 JavaScript - zastosowania po stronie przeglądarki 4 Biblioteka JQuery dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 2 / 228 Języki skryptowe Język skryptowy jest językiem programowania, który umożliwia uruchamianie w specjalnym środowisku programów (skryptów). Z reguły te programy są interpretowane a nie kompilowane. Przeznaczeniem tych języków jest automatyzacja powtarzalnych zadań, są również stosowane jako języki osadzone w większych aplikacjach. Ze względu na swoje właściwości są czasem nazywane językami bardzo wysokiego poziomu lub nawet językami specyfikacji. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 3 / 228 PHP Język powstał w połowie lat 90 dwudziestego wieku. Twórcą pierwszej wersji języka jest Rasmus Lerdorf. Jest językiem wieloplatformowym - implementacje można znaleźć dla różnych systemów (między innymi Windows, Linux, BSD). Wspiera programowanie obiektowe i strukturalne. Jest językiem dynamicznym z słabą kontrolą typów. Jego głównym zastosowaniem jest generowanie stron internetowych na przykład na podstawie danych wprowadzonych w formularz przez użytkownika. Jego implementacje są najczęściej interpreterami (uruchamianymi po stronie serwera). Najnowsza wersja języka to 7. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 4 / 228 Python Powstał we wczesnych latach 90 dwudziestego wieku jako następca języka ABC. Twórcą języka jest Guido van Rossum. Jest językiem wspierającym kilka paradygmatów programowania między innymi obiektowy, funkcyjny, strukturalny. Jest dynamicznym, interpretowanym językiem programowania. Filozofia programowania kładzie nacisk na prostotę i czytelność programów (The Zen of Python). Zarządzanie pamięcią jest realizowane z wykorzystaniem automatycznego odśmiecania. Obecnie są w użyciu dwie linie języka: Python 2.x (najnowsza wersja 2.7.11) i Python 3.x (najnowsza wersja 3.5.1). Najważniejsze implementacje to CPython, IronPython, Jython i PyPy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 5 / 228 Ruby Został stworzony w 1995 roku przez Japończyka Yukihiro Matsumoto. Popularność poza Japonią zdobył dzięki frameworkowi Ruby on Rails. Implementacje są interpreterami. Jest dynamicznym językiem obiektowym (wszystko jest obiektem) z wsparciem dla programowania funkcyjnego i strukturalnego. Jest językiem bardzo elastycznym - przede wszystkim dzięki możliwość podmiany zachowania obiektów w czasie uruchomienia programu - nawet typów wbudowanych. Posiada automatyczne odśmiecanie pamięci. Najnowszą wersją języka jest 2.3. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 6 / 228 Tcl Tcl (Tool Command Language) został stworzony przez Johna Outershouta. Jest interpretowanym językiem dynamicznym. Jest używany jako język rozszerzeń, skryptów powłoki itp. Jest ściśle zintegrowany z biblioteką graficzną Tk (Tcl/Tk). Umożliwia przenoszenie oprogramowania na różne platformy (Unix, Linux, Windows). Najnowsza wersja pochodzi z 2015 roku (8.6.4). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 7 / 228 Perl Perl powstał w 1987 roku, został stworzony przez Larry’ego Walla. Perl jest wysokopoziomowym językiem interpretowanym. Jest używany przede wszystkim do przetwarzania plików tekstowych, wykonywania operacja na powłoce, a także jako język rozszerzeń. Jest wieloplatformowy. Najnowsza wersja 5.18.2 pochodzi z stycznia 2014 roku. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 8 / 228 Lua Lua została stworzona przez Roberto Ierusalimschy-ego, Luiza Henrique de Figueiredo i Waldemara Celesa w 1993. Lua jest szybkim, lekkim językiem skryptowym. Jest językiem dynamicznie typowanym. Jest często używana do tworzenia skryptów dla gier. Uruchamiana na maszynie writualnej z odśmiecaniem pamięci. Najnowsza wersja 5.3.2 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 9 / 228 Podstawowa trójka internetowa Podstawą każdej większej strony internetowej są: HTML - specyfikacja zawartości strony CSS - specyfikacja wyglądu strony JavaScript - specyfikacja zachowania strony. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 10 / 228 JavaScript - ogólna charakterystyka JavaScript - wysokopoziomowy, dynamiczny, słabo typowany interpretowany język programowania. Zawiera wsparcie dla obiektowego i funkcyjnego stylu programowania. Jest wspierany przez najważniejsze przeglądarki. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 11 / 228 Składowe JavaScript Rdzeń - ECMAScript - opisuje składnię i semantykę języka (nie są opisywane szczegóły związane z przeglądarką). DOM (Document Object Model) - API dla XML, które zostało rozszerzone do użycia z HTML. DOM opisuje stronę jako hierarchię węzłów. BOM (Browser Object Model) - API umożliwiające dostęp i zmiany okna przeglądarki (przesuwanie, otwieranie, zamykanie). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 12 / 228 Historia JavaScript Język został stworzony przez Brendona Eicha w firmie Netscape w 1995. Oryginalną nazwą była Mocha, potem LiveScript a na końcu pu uzyskaniu pozwolenia od firmy Sun JavaScript. Język jest ustandaryzowany przez ECMA (1996) - w standardzie nosi nazwę ECMAScript (innym językiem, który spełnia ten standard z rozszerzeniami jest ActionScript). Najnowszą edycją standardu ECMAScript jest wersja 5.1 (czerwiec 2011). Następną wersją będzie wersja 6(Harmony lub ES.next). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 13 / 228 Narzędzia wspierające budowę oprogramowania JSFiddle - aplikacja online pozwalająca na uruchamianie i testowanie kodu http://jsfiddle.net/ (darmowe). Firebug - dodatek do Firefoxa - pozwala na testowanie i debugowanie kodu (darmowe). Aptana - oparte o Eclipse środowisko programowania aplikacji web (darmowe). WebStorm - środowisko programowania aplikacji web (niestety komercyjne). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 14 / 228 Osadzenie kodu w przeglądarce W dokumencie HTML można umieścić skrypt JavaScript pomiędzy znacznikami <script> i </script>. < s c r i p t l a n g u a g e=" JavaScript "> // ... // Treść skrytpu JavaScript // ... </ s c r i p t > Można się również odwoływać do zewnętrznych plików z kodem JavaScript: < s c r i p t s r c="p.js" t y p e="text/ javascript " l a n g u a g e=" JavaScript "></ s c r i p t > dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 15 / 228 Podstawowe elementy I Programy JavaScript zapisuje się używając Unicode. Jest rozróżniana wielkość liter - np. A i a są różnymi identyfikatorami. Białe znaki (spacja, tabulacja itp.) są z reguły pomijane w trakcie analizy leksykalnej. Jedynym wyjątkiem są znaki nowego wiersza, które mogą być separatorami instrukcji, gdy można jednoznacznie określić, gdzie instrukcja się kończy. Opcjonalnymi separatorami instrukcji są znaki średnika. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 16 / 228 Komentarze Komentarze są takie jak w Javie i C++. Jednolinijkowe są zapisywane pomiędzy znakami // i znakiem nowego wiersza. Wielolinijkowe komentarze są zapisywane pomiędzy znakami /* i */. Na przykład: // Komentarz jednlinijkowy var x = 1 0; /* Komentarz zajmuj ący wiele linii */ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 17 / 228 Podstawowe typy I Liczby 120 1.0 .5 1 . 2 E2 Wartości logiczne true false Łańcuchy znaków "Stała łań cuchowa " ’Inna stała łań cuchowa ’ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 18 / 228 Podstawowe typy II Data i czas v a r d1 = new Date ( 2 0 1 4 , 1 , 1 3 ) ; v a r d2 = new Date ( 2 0 1 4 , 1 , 1 4 , 1 0 , 0 , 0 ) ; Wyrażenia regularne - składnia Perla v a r s t r = " Liczby : 1, 2, 3" ; v a r w z o r z e c = /d+/g ; wzorzec . t e s t ( s t r ) ; s t r . search ( wzorzec ) ; s t r . match ( w z o r z e c ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 19 / 228 Obiekty I Obiekty są nieuporządkowaną kolekcją właściwości, które zawierają wartości typów podstawowych, innych obiektów lub funkcji. Każda z właściwości obiektu posiada swoją własną nazwę. Nazwy właściwości mogą być łańcuchami znaków zawierającymi spacje. Obiekty JavaScript (podobnie jak w Pythonie) są dynamiczne można dodawać i usuwać z nich właściwości. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 20 / 228 Obiekty II var s t u d e n t = { n a z w i s k o : " Kosmyk " , wiek : 22 , " numer indeksu " : 11212 daneOsobowe : f u n c t i o n ( ) { return t h i s . nazwisko + t h i s . wiek + t h i s [ " numer indeksu " ] ; } } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 21 / 228 Tablice I Tablica jest uporządkowaną kolekcją wartości. Tablice JavaScript są specjalnym rodzajem obiektów, nazwami właściwości są kolejne liczby całkowite (licząc od zera). Elementy tablicy w JavaScript mogą mieć dowolny typ (nawet różny). Dostęp do elementów jest realizowany za pomocą operatora indeksowania. Liczbę elementów tablicy można określić za pomocą własności length. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 22 / 228 Tablice II var tab1 = [ 1 , 2 , 3 , 4 ] ; v a r t a b 2 = [ 1 , true , "x" ] ; v a r t a b 3 = new A r r a y ( 2 0 ) ; f o r ( v ar i = 0 ; i < t a b . l e n g t h ; ++i ) tab1 [ i ] = 12; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 23 / 228 Wartości null i undefined Słowo null reprezentuje wartość specjalną używaną do zaznaczenia braku konkretnej wartości (jak null w Javie). Słowo undefined również oznacza brak wartości. jest wartością niezainicjowanej zmiennej, jest zwracane w sytuacji, gdy nie zostanie odszukana wartość odnosząca w tablicy, jest zwracane przez funkcję, która nie ma określonego typu wartości zwracanych. Wartość undefined jest reprezentowana przez własność obiektu globalnego. Poza opisaną różnicą oba słowa mogą być używane zamiennie. n u l l == undefined ; // true n u l l === undefined ; // false dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 24 / 228 Obiekty globalne Obiekt globalny jest obiektem dostarczającym własności dostępne dla całego programu JavaScript. W czasie startu interpretera są tworzone własności obiektu globalnego: globalne właściwości takie jak undefined, Infinity, NaN. funkcje globalne - np. isNan(), parseInt(). konstruktory np. Date(), RegExp(), String() itd. obiekty globalne jak Math i JSON. W kodzie najwyższego poziomu, który nie jest częścią funkcji, można użyć słowa kluczowego this do odwołania do obiektu globalnego. Dla aplikacji klienckich obiekt Window dostarcza obiektu globalnego object dla kodu JavaScript zawartego w oknie przeglądarki. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 25 / 228 Zmienne Nazwa identyfikatora zmiennej lub funkcji musi się zaczynać od liter (w tym Unicode), podkreślenia lub znaku dolara, po którym może nastąpić sekwencja liter, cyfr, znaków podkreślenia lub dolara. Słowa kluczowe: break, case, catch, continue, default, debugger, delete, do, else, false, finally for, function, if, in, instanceof, new, null, return, switch, this, throw, true, try, typeof var, void, while. Słowa zarezerwowane: class, const, enum, export, extends, import, super. W trybie strict są również zarezerwowane: implements, interface, let, package, private, protected, public, static, yield. Niedozwolone jest używanie identyfikatorów: arguments i eval. ECMAScript 3 rezerwuje wszystkie słowa kluczowe Javy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 26 / 228 Deklaracje zmiennych Zmienne przed użyciem powinny być zadeklarowane. Do deklaracji zmiennej używa się słowa kluczowego var, deklaracja może być połączona z inicjowaniem zmiennej. var x ; var i , j ; v a r y = "kot" ; Zmienne mogą przechowywać wartości różnych typów (nie jest do nich przypisany określony typ po definicji). var x = 1 . 0 ; x = "pies" ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 27 / 228 Zasięg widoczności zmiennych I Zasięg widoczności zmiennej zależy od miejsca definicji: obiekty globalne są widoczne w całym programie obiekty zdefiniowane w funkcjach (lokalne) są widoczne jedynie w ciele funkcji, w której zostały umieszczone. Zmienne są widoczne nawet przed swoją deklaracją, są przytwierdzone do początku funkcji (ang. hoisting). Funkcje mogą być zagnieżdżone - każda funkcja ma własny zasięg lokalny. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 28 / 228 Zasięg widoczności zmiennych II JavaScript nie posiada zasięgu blokowego (w przeciwieństwie do C++) var k = 0 ; i f ( i == 1 0 ) { var m = 154; f o r ( v ar l = 0 ; l < 5 ; ++l ) { // ... } //l nadal widoczne } //m zdefiniowane , ale nie musi być zainicjowane . dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 29 / 228 Wyrażenia i operatory I Operatory arytmetyczne: jednoargumentowe operatory +, −, ++, −−, mnożenie ∗, dzielenie /, dzielenie modulo % (działa także dla liczb zmiennoprzecinkowych), dodawanie + (i operator konkatenacji), odejmowanie −, Operatory bitowe: bitowa koniunkcja &, bitowa alternatywa |, bitowa alternatywa wyłączająca (xor) ^, bitowe zaprzeczenie ~, przesunięcie bitowe w lewo <<, przesunięcie bitowe w prawo ze znakiem >> (bity z lewej strony są wypełniane bitem znaku), przesunięcie bitowe w prawo >>> (bity z lewej strony zawsze zerowe), dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 30 / 228 Wyrażenia i operatory II Operatory relacyjne: równość i nierówność - operatory ==, ===, !=, !==. Operator === jest operatorem identyczności, działa jak ==, ale bardziej rygorystycznie oprócz sprawdzania wartości operandów sprawdzany jest również ich typ, nie są wykonywane żadne konwersje typów. "1" "1" 1.0 1.0 == t r u e // true === t r u e // false == 1 // true === 1 // true - ten sam typ Number Operatory porównania - <, >, <=, >= dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 31 / 228 Wyrażenia i operatory III Operator in - zwraca prawdę w wtedy i tylko wtedy, gdy wartość zapisana po lewej stronie jest nazwą właściwości obiektu zapisanego po prawej stronie (przy czym wartość stojąca po lewej stronie musi być łańcuchem znaków lub dać się do tego łańcucha znaków skonwertować). var obj = {a : 12}; "a" i n o b j ; // true "x" i n o b j ; // false Operator instanceof - zwraca prawdę wtedy i tylko wtedy gdy obiekt stojący po lewej stronie operatora jest instancją typu zapisanego po prawej stronie: dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 32 / 228 Wyrażenia i operatory IV v a r d a t a = new Date ( 2 0 1 4 , 1 , 1 ) ; d a t a i n s t a n c e o f Date ; // true d a t a i n s t a n c e o f Number ; // false d a t a i n s t a n c e o f O b j e c t ; // true dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 33 / 228 Wyrażenia i operatory V Operatory logiczne: koniunkcja - &&, alternatywa - ||, zaprzeczenie - !. Operatory przypisania - = i formy skrótowe (np. *=, +=, -= itd). x = x + 4; // jest równoważne x += 4 ; Operator warunkowy ?: a r g > 0 ? 1 : −1; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 34 / 228 Wyrażenia i operatory VI Operator typeof - operator jednoargumentowy, zwraca łańcuch znaków reprezentujący typ operandu. typeof typeof typeof typeof typeof 2 ; //" number " "X" ; // " string " n u l l ; //" object " undefined ; //" undefined " t r u e ; //" boolean " Operator delete - powoduje usuwanie własności obiektu lub elementu tablicy. var obj = {a : 1 , b : 2 } ; delete obj . a ; var tab = [ 3 , 4 , 5 ] ; delete tab [ 2 ] ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 35 / 228 Wyrażenia i operatory VII Operator void - jednoargumentowy, niezależnie od operandu zawsze zwraca wartość undefined - użyteczny, gdy należy pominąć przy wyświetlaniu wartości zwracane - na przykład bez wyświetlania w oknie przeglądarki. Operator przecinka - działanie takie jak w C++ - wartością zwracaną jest wartość wyrażenia z prawej strony, rzadko występuje samodzielnie - najczęściej używany w pętli for. // Wartością wyrażenia zapisanego poniżej jest 3 x = 1 , y = 2 , z = 3; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 36 / 228 Instrukcje I Instrukcja warunkowa - działanie takie jak w C++ i Javie wartościowane wyrażenie w nawiasach okrągłych jeżeli jest prawdziwe to wykonywana jest instrukcja zapisana po wyrażeniu, jeżeli jest fraza else to jest wykonywana w sytuacji, gdy wyrażenie w nawiasach okrągłych jest wartościowane do fałszu. i f ( x > 0) x = −x ; i f ( y > 0) { return y ; } else { r e t u r n −y ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 37 / 228 Instrukcje II Instrukcja wyboru - składniowo podobne do instrukcji z C++ i Javy, Wyrażenia etykiet są wartościowane w czasie uruchomienia. Etykieta może być wyrażeniem dowolnego typu. switch ( d z i e n ) { case " poniedzia łek" : return 1; case " wtorek " return 2; // ... default : r e t u r n −1; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 38 / 228 Instrukcje III Pętla while - działanie takie jak w C++, dopóki wyrażenie zapisane w nawiasach okrągłych zwraca prawdę wykonywane jest ciało pętli: var i = 0 ; while ( i < 100) { ++i ; } Pętla do while - działanie takie jak w C++, dopóki wyrażenie zapisane w nawiasach okrągłych zwraca prawdę wykonywane jest ciało pętli, pętla wykonywana jest przynajmniej raz: var i = 0 ; do { ++i ; } while ( i < 100) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 39 / 228 Instrukcje IV Pętla for - działanie takie jak w C++, Najpierw wykonywana jest część inicjalizacyjna, potem wykonywany jest test, ciało pętli jeżeli test jest wartościowany do prawdy, na końcu część związana z modyfikacją zmiennych (np. liczników). Iteracje są wykonywane aż do momentu, gdy test zwróci fałsz (lub pętla zostanie zakończona break, return). f o r ( v a r i = 0 ; i < 1 0 0 ; ++i ) { // ... } Pętla for in = używana do przechodzenia po własnościach obiektu lub elementach tablicy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 40 / 228 Instrukcje V f o r ( v ar tab [ i f o r ( v ar tab [ i i ] i ] dr inż. Andrzej Grosser = 0 ; i < t a b . l e n g t h ; ++i ) = i; in tab ) = i; Języki interpretowane Rok akademicki 2015/16 41 / 228 Instrukcje VI Skoki - break, continue - działanie takie jak w Javie - możliwy zapis z etykietą do której ma przejść sterowanie po osiągnięciu tej instrukcji. etykieta : f o r ( v ar i = 0 ; i < 1 0 ; ++i ) { f o r ( v ar j = 0 ; j < 1 0 ; ++j ) { f o r ( v ar k = 0 ; k < 1 0 ; ++k ) i f ( t a b [ k ] < 0 ) break e t y k i e t a ; } } Instrukcja powrotu - return. Zgłoszenie wyjątku - throw. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 42 / 228 Instrukcje VII Obsługa sytuacji wyjątkowych - obsługa podobna jak w Javie (ale tylko jeden blok catch) Kod, w którym może wystąpić wyjątek jest objęty blokiem try. Wyjątki są przechwytywane w bloku catch. Niezależnie od tego czy został zgłoszony jakikolwiek wyjątek wykonywany jest blok finally. try { // Normalny kod } catch ( e ) { // Kod obsługi wyjątku } finally { // Kod kończący } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 43 / 228 Funkcje I Definicja funkcja rozpoczyna się od słowa kluczowego function, po którym znajduje się zapisany w nawiasach okrągłych zbiór jej argumentów (rozdzielanych przecinkami) i ciało funkcji. Funkcje w JavaScript nie sprawdzają, ile argumentów dostają na wejściu. Argumenty wywołania funkcji są przechowywane w zmiennej arguments. Kolejne argumenty można uzyskać korzystając z operatora indeksowania. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 44 / 228 Funkcje II function kwadrat ( x ) { return x ∗ x ; } function kwadrat2 { return arguments [ 0 ] ∗ arguments [ 0 ] ; } kwadrat ( ) ; kwadrat (12) ; kwadrat (10 ,121 ,12) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 45 / 228 Literatura 1 D.Flanagan ”JavaScript: The Definitive Guide” wydanie szóste, O’Reilly Media 2011 2 N.C. Zakas ”Proffesional: JavaScript for Web Developers” wydanie trzecie, John Wiley & Sons 2012 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 46 / 228 Funkcje jako obywatele pierwszego rzędu I Funkcje są traktowane jako każda inna wartość: Można Można Można Można przekazywać funkcje do innych funkcji jako argumenty, zwracać jako wynik funkcję, definiować funkcje lokalne (zagnieżdżone), definiować funkcje anonimowe (nienazwane). Funkcje przyjmujące i zwracające funkcje to funkcje wyższego rzędu. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 47 / 228 Funkcje jako obywatele pierwszego rzędu II function przyklad ( fun ) { function l o k a l n a () { return fun () ; } return l o k a l n a ; } f u n k c j a = p r z y k l a d ( function ( ) { return 2∗2}) ; funkcja () ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 48 / 228 Domknięcia I JavaScript używa zasięgu leksykalnego (statycznego). Zasięg leksykalny oznacza, że gdy funkcja jest wykonywana używa zmiennych z miejsca, w którym została zdefiniowana a nie z miejsca, w którym została wywołana. Dla implementacji zasięgu leksykalnego konieczne jest przechowywanie środowiska, w którym została zdefiniowana funkcja (zbiór zmiennych wpływających na zachowanie funkcji). Połączenie obiektu funkcji z jej zasięgiem (wystarcza zbiór wiązań zmiennych wolnych) jest nazywany domknięciem (ang. closure). Wszystkie funkcje w JavaScript są domknięciami. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 49 / 228 Domknięcia II function zwierze () { v a r g a t u n e k = " orangutan " ; f u n c t i o n wewnetr zna ( ) { a l e r t ( gatunek ) ; } r e t u r n wewnetrzna ; } // ... v a r g a t u n e k = " goryl " ; zwierz = zwierze () ; zwierz () ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 50 / 228 Domknięcia III Zmienne wolne są przekazywane przez referencję. Jeżeli funkcja zwraca inną funkcję to przy każdym wywołaniu tworzone jest inne domknięcie. Daje to możliwość utworzenia zmiennych pomocniczych. function przyklad () { v ar l i c z b a = 0 ; v ar l i c z n i k = f u n c t i o n ( ) { a l e r t (++ l i c z b a ) ; } return l i c z n i k ;} zm = p r z y k l a d ( ) ; //1 2 zm ( ) ; zm ( ) ; //1 - inne domkni ęcie przyklad () () ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 51 / 228 Literały obiektowe Literałem obiektowym jest nazywana lista rozdzielonych przecinkami par (nazwa właściwości, wartość) umieszczona w nawiasach klamrowych. Nazwami właściwości są identyfikatory lub łańcuchy znaków. Wartością w parze są dowolne wyrażenia JavaScript. var pusty = { } ; var p r o s t o k a t = {a : 1 . 0 , b : 2 . 0 } ; var a u t o r = { i m i e : "Jan" , " drugie imie" : " Tadeusz " , n a z w i s k o : "Moziński" , adres : { m i e j s c o w o s c : " Warszawa " } }; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 52 / 228 Tworzenie obiektów z wykorzystaniem new Instrukcja new tworzy i inicjuje nowy obiekt. Po słowie kluczowym new musi wystąpić wywołanie funkcji konstruktora. Dla typów wbudowanych: var var var var o b i e k t = new O b j e c t ( ) ; t a b l i c a = new A r r a y ( ) ; d a t a = new Date ( ) ; wr = new RegExp ( "a+" ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 53 / 228 Tworzenie obiektów z wykorzystaniem Object.create() ECMAScript 5 definiuje do tworzenia obiektów metodę Object.create(). Metoda ta tworzy nowy obiekt używając swojego parametru jako prototypu tego obiektu. Metoda create umożliwia przekazywanie drugiego, opcjonalnego parametru, który opisuje właściwości nowego obiektu. // obj odziedziczy właściwości a i b var obj = Object . c r e a t e ({ a : 1 , b : 2 } ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 54 / 228 Programowanie obiektowe Wpływ na definicję nowego typu w JavaScript mają: konstruktor - obiekt funkcji, który definiuje nazwę dla nowej klasy, właściwości dodane w konstruktorze są polami i metodami (w przypadku podstawiania funkcji do właściwości) klasy. prototyp - część obiektu, która jest dziedziczona przez wszystkie obiekty klasy, obiekt instancji - jest instancją nowego typu, właściwości przypisane do obiektu po jego utworzeniu nie są współdzielone z innymi obiektami. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 55 / 228 Konstruktor I W terminologii JavaScript konstruktor to funkcja, która jest używana do inicjowania nowego obiektu. Konstruktor powinien być wywoływany z użyciem słowa kluczowego new (wywołany bez new utworzy właściwość obiektu globalnego). Każda funkcja JavaScript może być użyta jako konstruktor (poza funkcjami zwracanymi przez metodę Function.bind() - ECMAScript 5). Właściwość prototype konstruktora jest używana jako prototyp nowego obiektu - wszystkie obiekty są tworzone z wykorzystaniem jednego konstruktora i mają w ten sposób jeden typ. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 56 / 228 Konstruktor II f u n c t i o n Punkt ( x , y ) { this . x = x ; this . y = y ; this . odl = function () { r e t u r n Math . s q r t ( t h i s . x ∗ t h i s . x + t h i s . y ∗ this . y) ; } } // Tworzenie instancji p1 = new Punkt ( 1 , 2 ) // p2 - undefined - tylko wywołanie funkcji p2 = Punkt ( 3 , 4 ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 57 / 228 Prototypy I Każdy obiekt JavaScript posiada dwie części: wartość określającą jego zawartość, prototyp. Wartość obiektu jest tworzona na podstawie prototypu. Każdy literał obiektowy posiada ten sam prototyp Object.prototype. Prototyp może być określany z wykorzystaniem konstruktorów. Dostęp do prototypu - Object.getPrototypeOf(obj) Dodatkowo dostęp do prototypu (poza IE) jest możliwy z wykorzystaniem __proto__. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 58 / 228 Prototypy II var P r o s t o k a t = function ( a , b ) { this . a = a ; this . b = b ; } P r o s t o k a t . p r o t o t y p e . obwod = f u n c t i o n ( ) { return 2 ∗ t h i s . a + 2 ∗ t h i s . b ; } v a r p = new P r o s t o k a t ( 1 0 , 2 0 ) ; p . obwod ( ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 59 / 228 Prototypy III Mechanizm tworzenia typów w oparciu o prototypy jest dynamiczny. Obiekt dziedziczy właściwości prototypu, nawet w sytuacji, gdy prototyp zostanie zmieniony po utworzeniu obiektu. Umożliwia to rozszerzanie typów poprzez dodawanie nowych metod. Przedstawiony mechanizm działa również dla typów wbudowanych można rozszerzać liczby, łańcuchy, tablice itd. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 60 / 228 Prototypy IV Number . p r o t o t y p e . p r z e c i w n a = f u n c t i o n ( ) { r e t u r n −t h i s ; } v a r x = −1; x . przeciwna () ; // Usuwa białe znaki z lewej strony Stri ng . prototype . l t r i m = function () { r e t u r n t h i s . r e p l a c e ( / ˆ \ s +/, ’’ ) ; } //x - "X " var x = " X " ; x . ltrim () ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 61 / 228 Usuwanie właściwości I Do usuwania właściwości z obiektu służy operator delete. Operand delete musi być wyrażeniem służącym do dostępu do właściwości. Operator delete zwraca wartość prawdy, gdy usunięcie zakończyło się sukcesem lub nie spowodowało żadnego efektu. Można usuwać tylko właściwości własne obiektu. Operator delete zwraca wartość fałszu, gdy operacja usunięcia właściwości jest niemożliwa do przeprowadzenia. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 62 / 228 Usuwanie właściwości II o b j = { x : "A" , y : 1 2 } ; // Prawda delete obj . x ; // Prawda delete obj . x ; // Prawda delete obj . z ; // fałsz delete Object . prototype dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 63 / 228 Metody porównujące Operator równości JavaScript porównuje obiekty przez referencję a nie przez ich zawartość - obiekty są równe wtedy i tylko wtedy, gdy są tymi samymi obiektami. Porównywanie wartości poszczególnych składowych jest możliwe poprzez zdefiniowanie i późniejsze wykorzystanie metod. Punkt . p r o t o t y p e . e q u a l s = f u n c t i o n ( o b j ) { i f ( o b j == n u l l ) | | ( o b j . c o n s t r u c t o r !== Punkt ) return f a l s e ; r e t u r n t h i s . x == o b j . x && t h i s . y == o b j . y ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 64 / 228 Właściwości prywatne i uprzywilejowane I Publiczne właściwości są deklarowane wewnątrz metod obiektu w postaci this.nazwa. Publiczne metody są definiowane z wykorzystaniem prototypu: K l a s a . p r o t o t y p e . metoda = f u n c t i o n ( ) { . . . } Prywatne zmienne są deklarowane z wykorzystaniem var, mogą być osiągalne jedynie z wykorzystaniem funkcji prywatnych i uprzywilejowanych (nie każda jednak taka funkcja ma dostęp wykorzystanie domknięcia). Prywatne funkcje są definiowane wewnątrz konstruktora typu lub za pomocą konstrukcji: var f u n k c j a = function ( ) { . . . } Właściwości statyczne są definiowane jako Klasa.nazwa = expr;. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 65 / 228 Właściwości prywatne i uprzywilejowane II f u n c t i o n Kolo ( r , x0 , y0 , k o l o r ) { // Pola prywatne v a r x 0 = x0 ; v a r y 0 = y0 ; var r = r ; // Metoda uprzywilejowana t h i s . getR = f u n c t i o n ( ) { return r ; } // Pole publiczne this . kolor = kolor ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 66 / 228 Właściwości prywatne i uprzywilejowane III // Metoda publiczna // Konieczne wykorzystanie metody uprzywilejowanej // przy dostępie do zmiennych prywatnych Kolo . p r o t o t y p e . p o l e = f u n c t i o n ( ) { r e t u r n Math . PI ∗ t h i s . getR ( ) ∗ t h i s . getR ( ) ; } // Atrybut statyczny Kolo . l i c z b a = 0 k o l o = new Kolo ( 1 , 2 , 3 , " czerwony " ) ; // Atrybut instancji k o l o .m = 4 3 ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 67 / 228 Instrukcja with I Dostęp do atrybutów obiektów może być skracany z wykorzystaniem instrukcji wiążącej with. Zazwyczaj do dostępu do składowej używa się nazwy obiektu, operatora dostępu do składowej i składową: obj . x = 12; obj . y = 10; Można jednak użyc with: with ( o b j ) { x = 12; y = 10; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 68 / 228 Instrukcja with II W praktyce with jest kłopotliwe i może prowadzić do niejednoznaczności: with ( o b j ) { a = b; } Zapisaną powyżej instrukcję można interpretować jako: obj . a = b ; obj . a = obj . b ; a = obj . b ; a = b; Instrukcja zaburza powiązania nazw zmiennych - spowolnienie programów. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 69 / 228 Dziedziczenie I Dziedziczenie jest w JavaScript najczęściej z użyciem łańcuchowego łączenia prototypów: //X <- Y <- Z function X( ) { this . x = 10; this . f1 = function () { r e t u r n "X()" ; } } function Y( ) { this . y = 12; this . f2 = function () { r e t u r n "Y()" ; } } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 70 / 228 Dziedziczenie II function Z() { this . z = 14; this . f3 = function () { r e t u r n "Z()" ; } } // Implementacja dziedziczenia Y . p r o t o t y p e = new X ( ) ; Z . p r o t o t y p e = new Y ( ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 71 / 228 Tablice W JavaScript można przechowywać w tablicy wartości różnych typów. Tablice w JavaScript są dynamiczne - mogą zwiększać i zmniejszać swój rozmiar w trakcie działania programu. Indeksy w JavaScript są oparte na 32 bitowych liczbach. Indeksy nie muszą być ciągłe (jest możliwość tworzenia tzw. tablic rzadkich). W JavaScript tablice można traktować jako specjalny rodzaj obiektu, których właściwości są liczbami - dostęp do elementów jest jednak szybszy niż w przypadku właściwości obiektów. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 72 / 228 Tworzenie tablic I Literały tablicowe - elementy rozdzielane przecinkami zapisane w nawiasach kwadratowych. var pusta = [ ] ; var tab1 = [ 1 , 2 , 3 , 4 ] ; v a r t a b 2 = [ 1 , f a l s e , 1 . 1 , "x" ] ; var tab3 = [ [ 1 , 2 . 0 ] , 1 2 ] ; var tab4 = [ { a : 1 , b : 2 } , [ 1 , 2 ] ] ; var tab5 = [ 1 , , 2 ] ; // Rozmiar tab6 3 a nie 4 - dopuszczalny jest // zapis dodatkowego nadmiarowego przecinka var tab6 = [ , , , ] ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 73 / 228 Tworzenie tablic II Tworzenie tablic z wykorzystaniem konstruktora tablicowego tablica pusta: v a r t a b 1 = new A r r a y ( ) ; tablica o określonym rozmiarze - rezerwuje tylko pamięć nie są tworzone elementy ani właściwości. Rozmiarem może być zmienna: var n = 1 0 ; v a r t a b 2 = new A r r a y ( n ) ; jawne przekazanie elementów do konstruktora (musi być więcej niż jeden element): v a r t a b 3 = new A r r a y ( 1 , 2 , 3 , 4 , 5 ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 74 / 228 Dostęp do elementów tablic I Dostęp do elementów tablicy jest realizowany z wykorzystaniem operatora indeksowania. Dostęp do nieistniejących indeksów nie skutkuje błędem, lecz zwraca wartość undefined; var tab = [ 1 , 2 ] ; tab [ 1 0 ] t a b [ −2] Zapis do elementu pod nieistniejącym indeksem skutkuje powstaniem nowego elementu w tablicy. var tab = [ 1 , 2 ] ; tab [ 1 0 ] = 100; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 75 / 228 Dostęp do elementów tablic II Indeksem są z reguły dodatnie liczby całkowite - ale są również dopuszczalne inne wartości: łańcuchy znaków - jeżeli da się go skonwertować do liczby to jest używany jako indeks, jeżeli nie jest tworzona właściwość o takiej nazwie. liczba ujemna - tworzona jest właściwość o nazwie będącej łańcuchem przechowującym znakową reprezentację tej liczby. liczba rzeczywista - jeżeli nie posiada części ułamkowej to jest traktowana jako indeks, w przeciwnym razie zasady są takie same jak dla liczby ujemnej. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 76 / 228 Dostęp do elementów tablic III tab = [ 1 , 2 ] ; // tworzona jest właściwość "1.2" tab [ 1 . 2 ] = 10; // element o indeksie 100 t a b [ "100" ] = 1 2 ; // tworzona jest właściwość " -1.2" tab [ −1.2] = 120; // tworzona jest właściwość " -1" t a b [ −1] = 1 2 ; // dostęp do drugiego elementu tab [ 1 . 0 ] = 10; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 77 / 228 Rozmiar tablicy I Liczbę elementów w tablicy gęstej można poznać za pomocą właściwości length. W przypadku tablic rzadkich zwróci o jeden większy maksymalny możliwy indeks. Właściwość daje się ustawiać w przypadku mniejszych wartości od bieżącego rozmiaru nadmiarowe elementy są usuwane, w przypadku większych wartości od bieżącego rozmiaru zmienia się tylko wartość właściwości, nie są dostawiane żadne dodatkowe elementy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 78 / 228 Rozmiar tablicy II // tab. length == 3 tab = [ 1 , 2 , 3 ] // length wynosi 2, ale nie ma ż adnych element ów tab2 = [ , , ] // length wynosi 5, ale nie ma ż adnych element ów t a b 3 = new A r r a y ( 5 ) ; // length po wykonaniu tych instrukcji wynosi 11, // Jest tylko jeden element tab4 = [ ] tab4 [ 1 0 ] = 12; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 79 / 228 Rozmiar tablicy III tab5 = [ 1 , 2 , 3 , 4 ] ; // Nadal tylko 4 elementy tab5 . l e n g t h = 10; // Teraz już tylko 3 tab5 . l e n g t h = 3; // Teraz tablica pusta tab5 . l e n g t h = 0; // Odpowiednik tab5 = new Array (20); // Nie są tworzone elementy tab5 . l e n g t h = 20; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 80 / 228 Iterowanie elementów tablicy I Najczęściej przechodzi się po elementach tablicy z wykorzystaniem pętli for w postaci: var tab = [ 1 , 2 , 3 , 4 ] ; f o r ( v ar i = 0 ; i < t a b . l e n g t h ; ++i ) { c o n s o l e . log ( tab [ i ] ) ; } // lub wersja szybsza var tab = [ 1 , 2 , 3 , 4 ] ; var r o z m i a r = tab . l e n g t h ; f o r ( v ar i = 0 ; i < r o z m i a r ; ++i ) { c o n s o l e . log ( tab [ i ] ) ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 81 / 228 Iterowanie elementów tablicy II W sytuacji, gdy konieczne jest pominięcie elementów niezdefiniowanych lub nieistniejących, należy dodać dodatkowy test na te wartości (w komentarzu pominięcie również wartości null): var tab = [ 1 , , 3 , 4 ] ; f o r ( v ar i = 0 ; i < t a b . l e n g t h ; ++i ) { // if(! tab[i]) continue ; i f ( t a b [ i ] === undefined ) c o n t i n u e ; c o n s o l e . log ( tab [ i ] ) ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 82 / 228 Iterowanie elementów tablicy III Należy unikać pętli for - in - wynika to z tego, że będą również wyświetlane wartości odziedziczone po Array.prototype. Można je jednak odfiltrować za pomocą: f o r ( v ar e l i n t a b ) { i f ( ! t a b . hasOwnProperty ( e l ) ) continue ; console . log ( el ) ; } Nie ma gwarancji, w jakim porządku będą wyświetlane elementy! dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 83 / 228 Metody tablic I concat() - tworzy i zwraca nową tablicę złożoną z połączonej pierwotnej tablicy i argumentów. Spłaszcza najbardziej zewnętrzne tablice przekazywane w ten sposób (ich elementy są wstawiane jako kolejne elementy nowej tablicy). var tab = [ 1 , 2 , 3 ] ; // Zwraca [1 ,2 ,1 ,2] tab . concat (1 ,2) ; // Zwraca [1 ,2 ,1 ,2] tab . concat ( [ 1 ] , [ 2 ] ) ; // Zwraca [1 ,2 ,1 ,[2]] tab . concat ( [ 1 ] , [ [ 2 ] ] ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 84 / 228 Metody tablic II indexOf() i lastIndexOf() zwracają indeks pierwszego (lub ostatniego) wystąpienia określonej parametrem wartości (lub -1, jeżeli elementu o takiej wartości nie ma w tablicy): var tab = [ 1 , 2 , 3 , 4 ] ; t a b . i n d e x O f ( 2 ) ; //1 t a b . i n d e x O f ( 1 0 ) ; // -1 join() - łączy elementy tablicy w łańcuch znaków (opcjonalny parametr - separator): var tab = [ 1 , 2 , 3 , 4 ] ; t a b . j o i n ( ) ; // ’1,2,3,4’ t a b . j o i n ( " " ) ; // ’1 2 3 4’ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 85 / 228 Metody tablic III slice() - tworzy wycinek tablicy - tablicę zawierającą elementy podane indeksami. toString() - tworzy łańcuch reprezentujący tablicę i jej elementy. pop() - usuwa ostatni element tablicy i zwraca go. push() - dodaje nowy element (elementy) na koniec tablicy i zwraca nową długość tablicy. reverse() - odwraca kolejność elementów tablicy. sort() - sortuje zawartość tablicy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 86 / 228 Metody tablic IV every() - zwraca prawdę, jeżeli wszystkie elementy spełniają predykat. filter() - tworzy nową tablicę zawierająca elementy, które pasują do filtra. parametr funkcję. shift() - usuwa i zwraca pierwszy element tablicy, some() - zwraca prawdę, jeżeli choć jeden element spełnia predykat. unshift() - dodaje jeden lub więcej elementów na początek tablicy, zwraca nową długość tablicy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 87 / 228 Metody tablic V forEach() - wywołuje określoną parametrem funkcję na każdym elemencie tablicy: var tab = [ 1 , 2 , 3 ] ; // tab == [1 ,4 ,9] tab . forEach ( function ( x , i , t ) { t [ i ] = x ∗ x ; } ) ; v a r sum = 0 [ 1 , 2 , 3 ] . f o r E a c h ( f u n c t i o n ( x ) {sum += x } map() - tworzy nową tablicę zawierającą elementy, które uzyskano aplikując przekazywaną jako argument funkcję do każdego elementu pierwotnej kolekcji: var tab1 = [ 1 , 2 , 3 ] ; // tab2 == [1 ,4 ,9] v a r t a b 2 = t a b 1 . map ( f u n c t i o n ( x ) { r e t u r n x ∗ x ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 88 / 228 Metody tablic VI reduce() i reduceRight() - łączą kolejne elementy tablicy z użyciem przekazywanej funkcji - tworzy się w ten sposób pojedynczą wartość. Funkcja reduce() łączy elementy do najniższego indeksu, zaś reduceRight() od najwyższego. var tab = [ 1 , 2 , 3 , 4 ] ; // suma == 10 v a r suma = t a b . r e d u c e ( f u n c t i o n ( x , y ) { r e t u r n x + y ; } , 0) ; // suma2 == 10 v a r suma2 = t a b . r e d u c e R i g h t ( f u n c t i o n ( x , y ) { return x + y ; } , 0 ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 89 / 228 Metody tablic VII // t1 == [1 ,2 ,3 ,4] var t1 = tab . reduce ( function ( x , y ) { return x . concat ( y ) ;} , [ ] ) ; // t2 == [4 ,3 ,2 ,1] var t2 = tab . r e d u c e R i g h t ( function ( x , y ) { return x . concat ( y ) ; } , [ ] ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 90 / 228 Wyrażenia regularne I Wyrażenie regularne jest obiektem opisującym ciąg znaków. Wyrażenia regularne są użyteczne przy wyszukiwaniu ciągów znaków lub zamiany ciągów znaków W JavaScript wyrażenia regularne opisuje typ RegExp. JavaScript implementuje składnię wyrażeń regularnych Perla (większość elementów została przejęta z tego języka). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 91 / 228 Wyrażenia regularne II Wyrażenia regularne definiuje się korzystając z ukośnika (slash /) lub z konstruktora typu: v a r w z o r z e c = /ˆA / ; v a r w z o r z e c 2 = new RegExp ( "^A" ) ; Dopuszczalne jest użycie flag: i - dopasowanie niezależne od wielkości liter, g - wyszukanie wszystkich dopasowań a nie tylko jednego, m - tryb wieloliniowy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 92 / 228 Klasy znaków Symbol [...] [^...] . \w \W \s \S \d \D Co dopasowuje Dowolny znak w nawiasach Dowolny znak niewymieniony w nawiasach Dowolny znak (oprócz znaku nowego wiersza) Znak ASCII (cyfra, litera, znak podkreślenia) Znak, który nie jest znakiem ASCII. Biały znaku Unicode. Dowolny znak, który nie jest białym znakiem Unicode Cyfra ASCII Dowolny znak różny od cyfry ASCII. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 93 / 228 Powtórzenia Symbol {n,m} {n,} {n} ? + * Znaczenie Dopasowanie co najmniej n razy, lecz nie więcej niż m Dopasowanie n lub więcej razy Dopasowanie dokładnie n razy Opcjonalne dopasowanie Dopasowanie jeden lub więcej razy Dopasowanie zero lub więcej razy. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 94 / 228 Grupowanie i alternacja Symbol | (...) (?:...) \num Znaczenie Dopasowanie do prawego lub lewego podwyrażenia Grupowanie i numerowanie - zapamiętana grupa może być później użyta Tylko grupowanie Dopasowanie do tych samych znaków jak w przypadku grupy num dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 95 / 228 Dopasowanie do określonej pozycji Symbol ^ $ \b \B (?= p) (?! p) Znaczenie Dopasowanie do początku linii lub łańcucha Dopasowanie do końca linii lub łańcucha Dopasowanie do granicy słowa Dopasowanie do pozycji, która nie jest granicą słowa Pozytywne przeglądanie do przodu - wymagane dopasowanie do ciągu, ale ciąg nie jest konsumowany Negatywne przeglądanie do przodu - wymagany brak dopasowania do ciągu, ciąg nie jest konsumowany dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 96 / 228 Przykłady I /\ d { 1 , 4 } / // "1" "12" "1234" /\ d {4}/ // "1234" /\ s+domek\ s ∗/ //" domek " " domek " // "for" ale nie " forma ", " bufor ", " aforyzm " /\ b f o r \b | \ b i f \b | \ b w h i l e \b/ // ’a’ "b" / ( [ ’"]) [^’"]*\1/ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 97 / 228 Metody łańcuchów współpracujące z wyrażeniami regularnymi I Z wyrażeniami regularnymi współpracują metody łańcuchów znakowych - search(), replace(), match() i split(). Metoda search() umożliwia odszukanie indeksu, od którego rozpoczyna się wyraz dopasowujący do danego wyrażenia regularnego (lub -1, jeżeli takiego nie znajdzie): " MOLEK" . s e a r c h ( / [AO] l e k / i ) ; //1 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 98 / 228 Metody łańcuchów współpracujące z wyrażeniami regularnymi II Metoda replace() zwróci łańcuch, w którym zastąpi wyraz dopasowujący do określonego wyrażenia regularnego ciągiem przekazanym jako drugi argument (dozowolone jest użycie znaku $, za którym następuje cyfra): v a r t e k s t = "a b c d e" ; // Zwróci "a, b, c, d, e" t e k s t . r e p l a c e ( / ( \ s +)/g , ’,$1); dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 99 / 228 Metody łańcuchów współpracujące z wyrażeniami regularnymi III Metoda match() - umożliwia przekazanie jako argument wyrażenia regularnego i zwraca tablicę zawierającą wyniki dopasowania (rozróżnia globalne i nieglobalne przeszukiwanie). t e k s t = " abc@gmail .com" //[ ’abc@gmail .com ’, ’abc ’, ’gmail .com ’, // index: 0, input : ’abc@gmail .com ’ ] t e k s t . match ( / ( \w+)@( \ S+) / ) //[ ’abc@gmail .com ’ ] t e k s t . match ( / ( \w+)@( \ S+)/ g ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 100 / 228 Metody łańcuchów współpracujące z wyrażeniami regularnymi IV Metoda split() umożliwia podział łańcucha znaków względem granicy określonej wyrażeniem regularnym (zwraca tablicę łańcuchów znaków): v a r t e k s t = "1234 456 789 11223 " ; //[ ’1234’, ’456’, ’789’, ’11223 ’ ] t e k s t . s p l i t ( / \ s +/) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 101 / 228 Metody wyrażeń regularnych I Typ RegExp definiuje dwie metody pozwalające na wykonywanie operacji z wykorzystaniem wzorców - exec(), test(). Działanie metody exec() - działa podobnie jak match(), ale zwraca tablicę znaków o takiej samej postaci - ustawiane są właściwości index i lastIndex. W przypadku wyszukiwania globalnego, w kolejnej iteracji dopasowanie zaczyna się od pozycji lastIndex. Metoda test() pozwala na sprawdzenie czy dane wyrażenie regularne dopasowuje do jakiegoś fragmentu łańcucha znaków (zwraca wartość logiczną). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 102 / 228 Metody wyrażeń regularnych II v a r t e k s t = " JavaScript jest bardziej zakręcony\ od języka Java" ; var wzorzec = / Java /g ; var wynik ; w h i l e ( ( w y n i k = w z o r z e c . e x e c ( t e k s t ) ) != n u l l ) { c o n s o l e . l o g ( wynik [ 0 ] ) ; } w z o r z e c . t e s t ( t e k s t ) ; // true dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 103 / 228 Nowości w JavaScript 6 I Zasięg blokowy ECMAScript 5 var tab = [ ] ; f o r ( v a r i = 0 ; i < 5 ; ++i ) { tab [ i ] = function () { c o n s o l e . l o g ( " Numer " + i ) ; }; } // Numer 4 tab [ 2 ] ( ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 104 / 228 Nowości w JavaScript 6 II ECMAScript 6 var tab = [ ] ; f o r ( v a r i = 0 ; i < 5 ; ++i ) { l e t nr = i ; tab [ i ] = function () { c o n s o l e . l o g ( " Numer " + n r ) ; }; } // Numer 2 tab [ 2 ] ( ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 105 / 228 Nowości w JavaScript 6 III Stałe c o n s t EULER = 0 . 5 7 2 // Nie powiedzie się EULER = 0 . 5 Parametry domyślne funkcji function fun ( x , y ) { i f ( x === undefined ) x = 1 ; i f ( y === undefined ) y = 2 ; return x + y ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 106 / 228 Nowości w JavaScript 6 IV Iteratory i for..of let fibonacci = { [ Symbol . i t e r a t o r ] ( ) { l e t pre = 0 , cur = 1; return { next () { [ pre , c u r ] = [ c ur , p r e + c u r ] ; r e t u r n { done : f a l s e , v a l u e : c u r } } } } } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 107 / 228 Nowości w JavaScript 6 V f o r ( v ar n o f f i b o n a c c i ) { i f ( n > 1000) break ; console . log (n) ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 108 / 228 Nowości w JavaScript 6 VI function fun ( x , y ) { x = x | | 1; y = y | | 2; } function fun ( x = 1 , y = 2) { return x + y ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 109 / 228 Nowości w JavaScript 6 VII Skrócony zapis funkcji anonimowych (ang. arrow function) v a r k w a d r a t = x => x ∗ x ; v a r p r o s t o k a t = ( a , b ) => a ∗ b ; t a b . f o r E a c h ( v => { i f ( v % 5 === 0 ) w y n i k . push ( v ) } ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 110 / 228 Nowości w JavaScript 6 VIII Klasy c l a s s Punkt { constructor (x , y) { this . x = x ; this . y = y ; } dlugosc () { r e t u r n Math . s q r t ( x ∗ x + y ∗ y ) ; } } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 111 / 228 Nowości w JavaScript 6 IX Dziedziczenie class Figura { constructor (x , y) { // ... } } c l a s s Kwadrat e x t e n d s F i g u r a { constructor (x , y , a) { super (x , y ) ; // ... } } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 112 / 228 Document Object Model I Document Object Model (w skrócie DOM) jest podstawowym API do reprezentacji i modyfikacji zawartości dokumentów HTML i XML. Zagnieżdżona struktura dokumentów HTML lub XML jest reprezentowana w DOM za pomocą drzewa obiektów. Drzewo reprezentuje dokument w postaci węzłów przedstawiających tagi HTML (np <body>,<b>) i węzłów reprezentujących tekst. Korzeniem całego drzewa jest dokument jako całość. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 113 / 228 Document Object Model II <html> <head> <title>Przykład</title> </head> <body> <h1>Nagłówek</h1> <p>Zawartość <b>strony</b> </p> </body> </html> dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 114 / 228 Document Object Model III dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 115 / 228 Rodzaje węzłów DOM Dokument - Document HTMLDocument Dane znakowe - CharacterData Text - tekst, Comment - komentarz. Elementy - Element HTMLElement HTMLHeadElement HTMLBodyElement HTMLTableElement ... Atrybuty - Attr - reprezentują atrybuty elementów dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 116 / 228 Atrybuty węzłów - trawersacja DOM I Najważniejszymi atrybutami węzłów są: parentNode - zawiera węzeł rodzicielski (lub null dla węzłów, które nie mają rodzica), childNodes - tablica tylko do odczytu zawierająca reprezentacje węzłów potomnych, firstChild i lastChild - pierwszy i ostatni potomek węzła (lub null jeśli węzeł nie posiada dzieci), nextSibling, previousSibling - następne i poprzednie rodzeństwo węzła (węzły potomne tego samego węzła są rodzeństwem). Porządek jest określony występowaniem w dokumencie. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 117 / 228 Atrybuty węzłów - trawersacja DOM II nodeType -rodzaj węzła Document - 9 Element - 1 Text - 3 Comment - 8 DocumentFragment - 11 nodeValue - zawartość węzła tekstowego lub komentarza (Text i Comment), nodeName - nazwa tagu elementu zapisana wielkimi literami. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 118 / 228 Atrybuty elementów - trawersacja DOM Elementy przedstawiają tagi HTML - przedstawione właściwości umożliwiają przechodzenie po drzewie dokumentów bez odwiedzania węzłów tekstowych i komentarzy. Najważniejsze właściwości z tej grupy: children - jest to NodeList, ale zawiera tylko obiekty Element. firstElementChild i lastElementChild - podobne jak dla węzła, ale tylko elementy. nextElementSibling i previousElementSibling - rodzeństwo, które jest elementem, childElementCount - liczba elementów potomnych (zwraca to samo co children.length). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 119 / 228 Wybór elementów dokumentu I Do obiektu Document można odwołać się poprzez zmienną globalną document. Przekształcanie elementów jest możliwe dopiero po uzyskaniu odpowiedniego elementu. Dostęp do elementów dokumentów jest możliwy na wiele sposobów: za za za za za pomocą pomocą pomocą pomocą pomocą dr inż. Andrzej Grosser atrybutu id, atrybuty name, wyspecyfikowanej nazwy tagu, wyspecyfikowanej klasy arkusza styli, dopasowania do wyspecyfikowanego selektora CSS. Języki interpretowane Rok akademicki 2015/16 120 / 228 Wybór elementów dokumentu II Wszystkie elementy dokumentu HTML posiadają atrybut id. Wartość atrybutu id musi być unikalna wewnątrz dokumentu. Elementy wybiera się za pomocą funkcji getElementById() obiektu Document. // Na przykład w funkcji obsługi zdarzenia v a r x=document . g e t E l e m e n t B y I d ( " mojNaglowek " ) ; a l e r t ( x . innerHTML ) ; // Fragment kodu HTML <h1 i d=" mojNaglowek ">Nag ł ówek</h1> dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 121 / 228 Wybór elementów dokumentu III Atrybut name był używany do nazywania elementów fomularzy, które były wykorzystywane przy wysyłaniu danych na serwer. Atrybut name przypisuje nazwę dla elementu, w przeciwieństwie jednak do id nie musi być unikalny. Wybór elementu na pomocą atrybutu name jest możliwy po zastosowaniu funkcji getElementsByName(), jest ona metodą HTMLDocument - jest więc specyficzna dla dokumentów HTML. Wartością zwracaną przez wymienioną wcześniej metodą jest obiekt NodeList, który zachowuje się jak tablica tylko do odczytu obiektów Element. a l e r t ( document . getElementsByName ( " nazwa " ) [ 0 ] . value ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 122 / 228 Wybór elementów dokumentu IV Możliwy jest wybór wszystkich elementów o wyspecyfikowanym typie (lub nazwie tagu) za pomocą metody getElementsByTagName(). v a r p a r a g y = document . getElementsByTagName ( "p" ) ; Podobnie jak wcześniejsza metoda zwraca obiekt NodeList. Dla dokumentów HTML nie są rozróżniane przez metodę wielkości liter. Elementy również posiadają metodę getElementsByTagName(), ale w ich przypadku są zwracane elementy, które są potomkami tego elementu (są umieszczone wewnątrz). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 123 / 228 Wybór elementów dokumentu V Atrybut class HTML is listą zawierającą identyfikatory rozdzielone spacjami. Atrybut pozwala na definicję zbioru powiązanych ze sobą elementów dokumentu. Atrybut ten jest wykorzystywany w połączeniu z arkuszami styli. HTML5 definiuje metodę getElementByClassName() umożliwiającą wybór elementów dokumentu, które mają ten sam atrybut class. Metoda zwraca obiekt NodeList. Metoda może być używana przez elementy - umożliwiają wybór elementów potomnych, które posiadają tą samą wartość atrybutu class. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 124 / 228 Wybór elementów dokumentu VI // Znajdź wszystkie elementy posiadaj ące atrybut header v a r h e a d e r = document . g e t E l e m e n t B y C l a s s N a m e ( " header " ) ; // Znajdź wszystkich potomk ów elementu o id log , // którzy posiadaj ą nazwę klasy error . v a r l o g = document . g e t E l e m e n t B y I d ( "log" ) ; v a r e r r = l o g . g e t E l e m e n t B y C l a s s N a m e ( " error " ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 125 / 228 Wybór elementów dokumentu VII Arkusze stylów posiadają selektory, które umożliwiają opis elementów lub zbioru elementów wewnątrz dokumentu. Np: Element o id równym log - #log, Dowolny element <div> - div, Dowolny element z atrybutem error - .error Selektory mogą być nawet łączone - div.warning. Metodą umożliwiającą wybór elementów za pomocą selektorów jest querySelectorAll(). Metoda przyjmuje łańcuch znaków zawierający selektor CSS i zwraca NodeList. v a r dops = document . q u e r y S e l e c t o r A l l ( "div.note , div.alert" ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 126 / 228 Wybór elementów dokumentu VIII Wybór pierwszego pasującego elementu do selektora jest również możliwy za pomocą querySelector(). Jeżeli łańcuch znaków zawiera niepoprawny selektor to zwracany jest wyjątek. W celu dopasowania identyfikatora lub selektora, który nie jest składniowo poprawny z CSS (np zawiera dwukropek) znak musi być poprzedzony odwrotnym ukośnikiem. Znak odwrotnego ukośnika ma w JavaScript znaczenie specjalne, dlatego musi być wprowadzony podwójnie raz jako łańcuch JavaScript zaś drugi raz jako dla argumentu funkcji querySelector. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 127 / 228 Wybór elementów dokumentu IX <d i v i d="foo\bar"></d i v > <d i v i d="foo:bar"></d i v > <s c r i p t > // "# fooar" c o n s o l e . l o g ( ’#foo\bar ’ ) ; // Nie dopasowuje do niczego document . q u e r y S e l e c t o r ( ’#foo\bar ’ ) // "# foo\bar" c o n s o l e . l o g ( ’#foo \\ bar ’ ) ; // "# foo \\ bar" c o n s o l e . l o g ( ’#foo \\\\ bar ’ ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 128 / 228 Wybór elementów dokumentu X // Dopasowuje do pierwszego diva document . q u e r y S e l e c t o r ( ’#foo \\\\ bar ’ ) ; // Nie dopasowuje do niczego document . q u e r y S e l e c t o r ( ’#foo:bar ’ ) ; // Dopasowuje drugiego diva document . q u e r y S e l e c t o r ( ’#foo \\: bar ’ ) ; </ s c r i p t > dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 129 / 228 Dostęp do atrybutów HTML elementów I Każdy obiekt HTMLElement, który reprezentuje elementy dokumentu HTML definiuje właściwości, które odzwierciedlają atrybuty HTML tego tagu. HTMLElement definiuje uniwersalne właściwości takie jak id. Są również specyficzne dla elementów atrybuty - np. dla obrazka src. v a r o b r a z = document . g e t E l e m e n t B y I d ( " obrazek " ) ; var o b r a z U r l = obraz . s r c ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 130 / 228 Dostęp do atrybutów HTML elementów II Właściwości elementów, mimo że HTML nie rozróżnia wielkości liter w atrybutach, zapisuje się małymi literami (wymagania składni JavaScript). Atrybuty, które są słowami kluczowymi JavaScript poprzedza się przedrostkiem html - np dla for - htmlFor. wyjątkiem dla tej reguły jest className dla atrybutu class. Typ właściwości zależy od tego co przechowuje najczęściej są to łańcuchy znaków (ale np. dla obsługi zdarzeń Function lub null). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 131 / 228 Odczyt/zapis atrybutów niestandardowych I Typ Element definiuje także funkcje getAttribute() i setAttribute() - są one użyteczne: do odczytu i ustawiania niestandardowych atrybutów HTML, do odczytu i zapisu atrybutów dokumentów XML. Wartości atrybutów są zawsze traktowane jako łańcuchy znaków: v a r d l g = p a r s e I n t ( o b r a z . g e t A t t r i b u t e ( " width " ) ) ; o b r a z e k . s e t A t t i b u t e ( " class " , " miniaturka " ) ; Metody te mogą być również używane dla standardowych atrybutów nazwy są zapisywane normalnie nawet dla atrybutów będących słowami kluczowymi JavaScript. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 132 / 228 Odczyt/zapis atrybutów niestandardowych II Element definuje dodatkowe dwie metody: hasAttribute() - pozwala sprawdzić czy podany atrybut istnieje, removeAttribute() - umożliwia usunięcie atrybutu. Dokumenty XML, które dołączają atrybuty z innej przestrzeni nazw używają metod getAttributeNS(), setAttibuteNS(), hasAttributeNS() i removeAttributeNS() - przejmują dwa parametry: pierwszy określaja przestrzeń nazw, drugi określa atrybut w tej przestrzeni nazw. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 133 / 228 Zawartość elementu I W zależności do potrzeb zawartość elementu (content) może być definiowana jako: łańcuch HTML - łańcuch zawierający tagi HTML np. Tekst z <b>tagami</b> html, czysty tekst - czysty łańcuch tekstowy, bez tagów HTML np. dla powyższego łańcucha będzie to Tekst z tagami html, węzeł typu Text - Element zawiera jako potomka tego rodzaju węzeł. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 134 / 228 Zawartość elementu II Odczyt właściwości innerHTML elementu pozwala poznać zawartość w postaci HTML. Zapis tej właściwości wywołuje parser HTML przeglądarki i zastępuje zawartość elementu nowym. Właściwość innerHTML może być używana w dokumentach HTML i XML. Element posiada również właściwość outerHTML - oprócz zawartości dołączone są również otwierające i zamykające tagi elementu. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 135 / 228 Zawartość elementu III Czysty tekst można uzyskać za pomocą właściwości textContent. Właściwość umożliwia uzyskanie zawartości tekstowej węzła i jego potomków (konkatenacja). W IE jest właściwość jest dostępna od wersji 9. document . getElementsByTagName ( " BUTTON " ) [ 0 ] . textContent ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 136 / 228 Modyfikacja dokumentu Oprócz przechodzenia dokumentu i zmiany właściwości elementów i węzłów tekstowych możliwa jest zmiana dokumentu na poziomie indywidualnych węzłów. Dokument definiuje kilka metod do tworzenia obiektów elementów i tekstowych a węzeł (Node) definiuje metody do wstawiania, usuwania i zamiany węzłów w drzewie dokumentu. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 137 / 228 Tworzenie węzłów Do tworzenia węzłów elementów służy metoda dokumentu createElement(). Przyjmuje ona tag elementu (wielkość liter nie ma znaczenia w przypadku HTML, ma zaś znaczenie w XML). v a r elem = document . c r e a t e E l e m e n t ( ’script ’ ) ; W podobny sposób są tworzone węzły tekstowe, do tego celu służy metoda createTextNode(). Przekazywany argument jest zawartością tego węzła. v a r w z l = document . c r e a t e T e x t N o d e ( " Zawarto ść" ) ; Do tworzenia komentarzy służy metoda createComment(). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 138 / 228 Wstawianie węzłów Po utworzeniu nowego węzła należy go wstawić do dokumentu z wykorzystaniem metod węzła - appendChild() lub insertBefore(). Metoda appendChild() jest wywoływana dla elementu, do którego należy wstawić zawartość - wstawiony węzeł będzie ostatnim potomkiem tego elementu (lastChild). Metoda insertBefore() pobiera dwa argumenty, pierwszym jest węzeł, który będzie wstawiany, zaś drugim argumentem jest węzeł, przed którym będzie on wstawiony (metoda jest wywoływana dla rodzica tego węzła). Metoda może przyjmować jako drugi argument null - zachowuje się wtedy jak appendChild(). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 139 / 228 Usuwanie i zastępowanie węzłów Metoda removeChild() usuwa węzeł z drzewa dokumentu. Metoda musi być wywołana w węźle rodzicielskim danego węzła: node . p a r e n t N o d e . r e m o v e C h i l d ( node ) ; Metoda replaceChild() zastępuje jeden węzeł innym. Metoda musi być wywoływana dla węzła rodzicielskiego węzła zastępowanego: node . p a r e n t N o d e . r e p l a c e C h i l d ( document . c r e a t e T e x t N o d e ( " Zawarto ść" ) , node ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 140 / 228 Obiekt Window I Obiekt Window reprezentuje okno przeglądarki,odnosi się do niego z wykorzystaniem identyfikatora window. Obiekt Window jest obiektem globalnym. Obiekt Window definiuje szereg właściwości i metod pozwalających na: używanie timerów, zmianę lokalizacji przeglądanej strony, przeglądanie historii, obsługę błędów, uzyskiwanie informacji o ekranie, wyświetlanie prostych okien dialogowych, pracę z wieloma oknami i ramkami. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 141 / 228 Timery I Metody obiektu Window - setTimeout() i setInterval() pozwalają na zarejestrowanie funkcji wywoływanych raz lub wielokrotnie po określonym przedziale czasu. Metoda setTimeout() wywołuje wyszczególnioną funkcję po upływie określonej liczby milisekund. Metoda zwraca wartość, która może być wykorzystana do anulowania wykonania zaplanowanej funkcji (metoda clearTimeout(). Metoda setInterval() działa podobnie jak wymieniona wcześniej setTimeout() z wyjątkiem tego, że stale powtarza wywołanie określonej funkcji. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 142 / 228 Timery II v a r myVar = s e t I n t e r v a l ( mojTimer , 1 0 0 0 ) ; f u n c t i o n mojTimer ( ) { v ar d = new Date ( ) ; v ar t = d . t o L o c a l e T i m e S t r i n g ( ) ; document . g e t E l e m e n t B y I d ( "demo" ) . innerHTML=t ; } function zatrzymajTimer () { c l e a r I n t e r v a l ( myVar ) ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 143 / 228 Właściwość location I Właściwość location (obiekt Location odnosi się do adresu dokumentu wyświetlanego obiektu w oknie przeglądarki. Obiekt location posiada właściwości i metody: href - przechowuje pełny adres, hash - przechowuje część związaną z identyfikatorem fragmentu (#) host - przechowuje nazwę hosta i port, hostname - przechowuje adres hosta, port - przechowuje port, search - przechowuje fragment adresu za znakiem zapytania (część zapytania, assign() - ładuje nowy dokument, reload() - przeładowuje bieżący dokument, replace() - zastępuje bieżący dokument nowym. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 144 / 228 Historia przeglądania I Historię przeglądarki reprezentuje właściwość history obiektu Window. Obiekt History jest listą dokumentów i stanów dokumentów. Skrypty nie mają bezpośredniego dostępu do przechowywanych adresów. Metody back() i forward() - działają jak przycisk przeglądarki <i ->. Metoda go() pozwala podać ile stron do przodu (lub do tyłu przy ujemnych liczbach) należy przesunąć się w historii przeglądarki. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 145 / 228 Informacje o przeglądarce i ekranie I Informacje o przeglądarce przechowuje właściwość navigator obiektu Window. Obiekt typu Navigator posiada właściwości: appName - przechowuje pełną nazwę przeglądarki, appVersion - przechowuje informacje o wersji przeglądarki, userAgent - przechowuje łańcuch jaki przeglądarka wysyła w nagłówku USER-AGENT. platform - łańcuch identyfikujący system operacyjny, na którym przeglądarka jest uruchomiona. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 146 / 228 Informacje o przeglądarce i ekranie II Właściwości ekranu (rozdzielczość, liczba kolorów) reprezentuje atrybut screen obiektu Window. Właściwości obiektu Screen reprezentujące wysokość i szerokość ekranu w pikselach to odpowiednio height i height. Właściwości availWidth i availHeight reprezentują wielkość ekranu pomniejszoną o piksele które zajmuje interfejs np. pasek zadań. Głębia koloru jest reprezentowana przez colorDepth. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 147 / 228 Proste okna dialogowe I Obiekt Window dostarcza trzech metod pozwalających na wyświetlanie prostych okienek dialogowych - alert(), confirm() i prompt(). Metoda alert() wyświetla wiadomość dla użytkownika aż do momentu, w którym ją zamknie. Metoda confirm() wyświetla wiadomość i oczekuje, że użytkownik kliknie przycisk Ok lub Anuluj. W zależności od podjętej w ten sposób decyzji jest zwracana odpowiednia wartość logiczna. Metoda prompt() wyświetla wiadomość i oczekuje dostarczenia przez użytkownika łańcucha znaków, zwraca tą wartość łańcucha. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 148 / 228 Proste okna dialogowe II Istnieje także metoda showModalDialog() pozwalająca w oknie wyświetlić dialog z sformatowaną zawartością. Metoda ta przyjmuje jako pierwszy argument url specyfikujący zawartość okna dialogowego. Drugim argumentem wywołania tej metody są wartości, które będą dostępne dla skryptu w dialogu - dostęp do nich jest możliwy z wykorzystaniem window.dialogArguments. Trzecim argumentem jest niestandardowa lista par przedzielanych średnikami - pozwalają one na konfigurowanie rozmiaru i innych własności okna dialogowego. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 149 / 228 Proste okna dialogowe III Okno wyświetlane z pomocą metody showModalDialog() jest modalne, co oznacza, że do dalszej pracy z aplikacją (oknem przeglądarki) konieczne jest zamknięcie go. Okno jest wyświetlane do momentu jego zamknięcia - gdy okno jest zamykane właściwość window.returnValue staje się wartością wywołania metody. Okno można zamknąć programowo (przydatne dla przycisków np. Ok) za pomocą metody close() obiektu Window. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 150 / 228 Proste okna dialogowe IV <body> <head></head> <form> <fieldset id="fields"></fieldset> <button onclick="akceptuj()">Potwierdź</button> <script> ... </script> </form> </body> dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 151 / 228 Proste okna dialogowe V var a r g s = dialogArguments ; v a r t e x t = "<legend > Podaj imię i nazwisko </ legend >" t e x t += "<label >Imię<input id=’im ’></label ><br/>" t e x t += "<label >Nazw.< input id=’naz ’></label ><br/>" document . g e t E l e m e n t B y I d ( " fields " ) . innerHTML = t e x t ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 152 / 228 Proste okna dialogowe VI function akceptuj () { window . r e t u r n V a l u e = { } ; window . r e t u r n V a l u e . i m i e = document . g e t E l e m e n t B y I d ( "imie" ) . v a l u e ; window . r e t u r n V a l u e . n a z w i s k o = document . g e t E l e m e n t B y I d ( "naz" ) . v a l u e ; window . c l o s e ( ) ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 153 / 228 Obsługa błędów Właściwość onerror obiektu Window jest uchwytem do funkcji obsługi błędów - jest ona wywoływana, gdy zdarzy się nieobsłużony wyjątek - komunikat o błędzie jest wyświetlany w konsoli JavaScript przeglądarki. Przypisanie do tej właściwości funkcji spowoduje, że stanie się ona funkcją obsługi błędów dla okna. Właściwość pochodzi z okresu, gdy nie było obsługi wyjątków z wykorzystaniem bloków try - catch Rzadko używane, przydatne do zapisu logów o błędach w czasie tworzenia aplikacji. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 154 / 228 Literatura 1 D.Flanagan ”JavaScript: The Definitive Guide” wydanie szóste, O’Reilly Media 2011 2 https://developer.mozilla.org/en-US/docs/Web/API 3 http://www.w3schools.com/jsref/ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 155 / 228 Zdarzenia I JavaScript używa asynchronicznego modelu obsługi zdarzeń. Przeglądarka generuje zdarzenie w sytuacji, gdy wykona się coś istotnego dla dokumentu, osadzonych elementów lub przeglądarki. Na przykład zdarzenie generowane są przy: klikinięciu przez użytkownika w przycisk, naciśnięciu przez użytkownika klawisza z klawiatury, załadowaniu całego dokumentu w przeglądarce. Zdarzenia są obsługiwane przez zarejestrowane funkcje, które są wywoływane, gdy określone zdarzenie zostanie zgłoszone. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 156 / 228 Przepływ zdarzeń DOM Przepływ zdarzeń w DOM wyróżnia trzy fazy: fazę przechwytywania (ang. capture phase) fazę celu (ang. target phase), fazę bąbelkowania (ang. bubble phase). W fazie przechwytywania obiekt zdarzenia jest przekazywany do kolejnych przodków widoku aż do rodzica celu. W fazie celu obiekt zdarzenia osiąga cel zdarzenia. W fazie bąbelkowania obiekt zdarzenia jest przekazywany w odwrotnej kolejności jak w fazie przechwytywania (od rodzica celu do widoku). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 157 / 228 Rejestrowanie obsługi zdarzeń Podstawowymi sposobami rejestrowania funkcji obsługi zdarzeń są: ustawienie właściwości obiektu lub elementu dokumentu, przekazanie funkcji obsługi zdarzeń do metod obiektu lub elementu. Każdą z wymienionych metod można użyć w kodzie JavaScript a dla elementów dokumentu można bezpośrednio ustawiać atrybuty w kodzie HTML. Funkcje obsługi zdarzeń są rejestrowane przez standardową metodę addEventListener() (w IE8 i starszych funkcja attachEvent()). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 158 / 228 Obiekt zdarzenia Obiekt zdarzenia jest przekazywany do funkcji obsługi jako pojedynczy argument tej funkcji. W ten sposób można uzyskać informacje dotyczące zdarzenia, na przykład: type - typ zgłoszonego zdarzenia, cancelable - pozwala sprawdzić czy zdarzenie może być wycofane, detail - dodatkowe informacje związane z zdarzeniem, bubbles - pozwala sprawdzić czy zdarzenie obsługuje fazę bąbelkowania. currentTarget - element, którego funkcją obsługi zdarzeń obsługuje w tej chwili zdarzenie. evenPhase - faza zdarzenia, podczas której została wywołana funkcja obsługi zdarzenia. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 159 / 228 Zdarzenia związane z myszą I Zdarzenie click - zdarzenie zgłaszane jest po zwolnieniu klawisza myszy po kliknięciu. Zdarzenie dbclick - zdarzenie zgłaszane jest po podwójnym wciśniśnięciu i zwolnieniu klawisza myszy (musi nastąpić w określonym czasie). Zdarzenie mousedown - zdarzenie zgłaszane jest po wciśnięciu klawisza myszy. Zdarzenie mouseup - zdarzenie występuje po zwolnieniu klawisza myszy, jest zwykle wykorzystywane przy obsłudze mechanizmu przeciągnij i upuść. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 160 / 228 Zdarzenia związane z myszą II Zdarzenie mouseover - zdarzenie jest zgłaszane, gdy kursor najedzie na określony element strony, jest wykorzystywane przy obsłudze rozwijanych menu. Zdarzenie mouseout - jest zgłaszane po wyjściu kursora myszy poza dany element. Zdarzenie mousemove - występuje po każdym ruchu myszy, pozwala sprawdzić bieżącą pozycję kursora na ekranie. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 161 / 228 Zdarzenia związane z klawiaturą Zdarzenie keypress - jest zgłaszane po wciśnięciu klawisza z klawiatury, jest zgłaszane do momentu zwolnienia klawisza. Zdarzenie keydown - w zależności od przeglądarki może być obsługiwane tak jak keypress (IE, Safari, Chrome) lub być zgłaszane raz po wciśnięciu klawisza z klawiatury (Opera, Firefox). Zdarzenie zachodzi po keypress. Jest zgłaszane dla znaków drukowalnych (nie dotyczy Firefoxa). Zdarzenie keyup - jest zgłaszane po zwolnieniu klawisza. Zdarzenie textinput - jest wyzwalane, gdy użytkownik wprowadzi tekst niezależnie od jego źródła (klawiatura, ze schowka, systemu rozpoznawania mowy itp.). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 162 / 228 Ajax I Protokół HTTP specyfikuje komunikację przeglądarki z serwerem webowym. HTTP opisuje w jaki sposób przeglądarki uzyskują dokumenty i wysyłają dane do serwera, a także w jaki sposób serwera odpowiada na uzyskane żądania. Jest możliwe sterowanie tym procesem za pomocą JavaScript - między innymi komunikacja z serwerem bez potrzeby przeładowania strony. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 163 / 228 Ajax II Termin Ajax opisuje architekturę aplikacji webowych, która pozwala na pisanie skryptów sterujących HTTP. Kluczową cechą Ajax jest wspomniana wcześniej możliwość wymiany danych z serwerem bez potrzeby przeładowania całej strony. Ta właściwość pozwala na lepszą responsywność aplikacji webowych użytkownik nie musi czekać na uzyskanie wszystkich danych. Aplikacja może wczytać tylko niezbędne dane (np. nieskomplikowaną stronę startową), reszta elementów może się pojawić dopiero, gdy będzie potrzebna. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 164 / 228 Ajax III Terminem uzupełniającym Ajax jest Comet - w tym przypadku serwer inicjuje komunikację i asynchronicznie wysyła komunikaty do klienta. Do wysyłki danych serwer nie musi czekać na jawne żądania od klienta. W Ajax klient wyciąga (pull) dane od serwera, zaś w Comet serwer popycha (push) dane do klienta. Ten sposób komunikacji jest możliwy z wykorzystaniem stałego połączenia pomiędzy klientem a serwerem. Brakuje bibliotek wspierających tego typu komunikację. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 165 / 228 XMLHttpRequest I Przeglądarki definiują API do HTTP z wykorzystaniem klasy XMLHttpRequest. Każda instancja tej klasy reprezentuje pojedynczą parę żądanie odpowiedź. Metody tej klasy pozwalają na wyspecyfikowanie szczegółów żądania i wyszczególnienie danych uzyskanych w odpowiedzi. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 166 / 228 XMLHttpRequest II 1 Utworzenie nowego obiektu XMLHttpRequest. 2 Specyfikacja żądania z wykorzystaniem open() podaje się metodę przekazywania danych i URL. 3 Specyfikacja sposobu obsługi odpowiedzi serwera - np. kod obsługi zdarzenia onreadystatechange. 4 Wysłanie żądania z wykorzystaniem metody send(). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 167 / 228 XMLHttpRequest III function getContent () { v a r r e q u e s t = new XMLHttpRequest ( ) ; r e q u e s t . open ( "GET" , "plik.txt" ) ; request . onreadystatechange = handler ; r e q u e s t . send ( n u l l ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 168 / 228 XMLHttpRequest IV function handler () { i f ( r e q u e s t . r e a d y S t a t e == 4 ) i f ( r e q u e s t . s t a t u s == 2 0 0 ) { v ar e l = document . g e t E l e m e n t B y I d ( "txt" ) ; v ar t x t N o d e = document . c r e a t e T e x t N o d e ( request . responseText ) ; e l . appendChild ( txtNode ) ; } return true ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 169 / 228 jQuery I JavaScript posiada rozbudowane API (szczególnie dotyczące aplikacji klienckich), które w różnym stopniu jest wspierane przez przeglądarki. Różnice pomiędzy przeglądarkami da się zniwelować korzystając z zewnętrznych bibliotek. Jedną z bibliotek narzędziowych JavaScript zaprojektowanych do ukrycia różnic pomiędzy przeglądarkami i uproszczenia powszechnie występujących zadań jest jQuery. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 170 / 228 jQuery II Instalacja jQuery polega na ściągnięciu ze strony jquery.com/downoload skryptu jquery-X.Y.Z.min.js (X, Y i Z są zastępowane numerami wersji) i umieszczeniu go w katalogu projektu. Skrypt umieszcza się w kodzie za pomocą tagów: <script src="jquery-X.Y.Z.min.js></script> Alternatywnym sposobem jest umieszczenie adresu sieciowego zawierającego bibliotekę. Są dostępne dwie wersje, przy czym wersja 2.X.X nie wspiera już IE w wersjach 6, 7 i 8. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 171 / 228 jQuery III Biblioteka jQuery posiada elastyczną składnię zaprojektowaną do odwoływania się do elementów dokumentu. W ten framework wbudowano metody umożliwiające tworzenie zapytań zwracających elementy dopasowujące do określonego selektora. Zawiera również metody do manipulacji wybranymi elementami. Umożliwia także stosowanie programowania funkcyjnego do wykonywania operacji na zbiorach elementów (traktowanych jako całość). Posiada specjalne idiomy do wyrażania sekwencji operacji. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 172 / 228 jQuery IV Biblioteka definiuje pojedynczą funkcję globalną jQuery(). Biblioteka wprowadza także skróconą nazwę tej funkcji w postaci znaku $. Funkcja ta zwraca obiekt, który reprezentuje zbiór elementów dokumentu (wynik jQuery, zbiór jQuery, opakowany zbiór). v a r e l e m s = $ ( "div" ) ; Na rzecz utworzonego obiektu jQuery są wywoływane odpowiednie metody. $ ( "p.inf" ) . c s s ( " bgcolor " , "red" ) . show ( "fast" ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 173 / 228 Selektory jQuery I Funkcja jQuery używa podobnej składni selektorów jak querySelectorAll(). $ ( "div" ) // Wszystkie div -y $ ( "# komunikat " ) // Element o id komunikat $ ( ". submenu " ) // Selektor klasy // Wszystkie odnośniki umieszczone wewnątrz // elementu o id komunikat $ ( "# komunikat a" ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 174 / 228 Selektory jQuery II Użycie biblioteki daje kilka bardzo ważnych korzyści: Możliwe jest jej użycie w przeglądarkach, które nie wspierają funkcji querySelectorAll(). Selektory CSS3 są dostępne we wszystkich przeglądarkach a nie tylko w tych, które wspierają CSS3. Obiekt tablicowy zwrócony przez jQuery jest łatwiejszy w użyciu od obiektu NodeList zwróconego przez funkcję querySelectorAll(). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 175 / 228 Getery i setery jQuery I Biblioteka jQuery dostarcza możliwość operowania na atrybutach HTML, stylach CSS, zawartości elementów i geometrii elementów. Biblioteka używa pojedynczych metod jako geterów i seterów - jeżeli jest przekazywana nowa wartość do metody - to jest ona ustawian, w przeciwnym razie zwracana bieżąca wartość atrybutu. Ustawiane są własności dla wszystkich elementów obiektu jQuery uzyskanego z zapytania. Zwracana jest wartość atrybutu tylko dla pierwszego elementu. Do ustawiania wartości można przekazywać obiekt jako argument. Dozwolone jest także przekazywanie funkcji - oblicza ona wartość jaka ma być ustawiona. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 176 / 228 Getery i setery jQuery II Metoda attr() - pozwala na ustawianie i odczytywanie atrybutów HTML. // Zwraca wartość atrybutu $ ( ’# obrazek img ’ ) . a t t r ( s r c ) // Pozwala ustawi ć warto ść atrybutu $ ( ’# obrazek img ’ ) . a t t r ( s r c , ’images /new.png ’ ) $ ( "a" ) . a t t r ( " target " , f u n c t i o n ( ) { i f ( t h i s . h o s t == l o c a t i o n . h o s t ) r e t u r n " _self " e l s e r e t u r n " _blank " ; } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 177 / 228 Getery i setery jQuery III Metoda css() wspiera arkusze styli. $ ( "p" ) . c s s ( "font - weight " ) //Błąd - nie można pobiera ć stylów złoż onych $ ( "p" ) . c s s ( "font" ) // Ale można je ustawia ć $ ( "h1" ) . c s s ( "font" , "bold italic large serif " ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 178 / 228 Getery i setery jQuery IV Metoda val() pozwala ustawiać i odczytywać atrybut value elementów formularzy HTML. $ ( "# nazwisko " ) . v a l ( ) $ ( "#mail" ) . v a l ( " Niepoprawny mail" ) // Reset pól tekstowych do warto ści domyś lnych $ ( " input:text" ) . v a l ( f u n c t i o n ( ) { return t h i s . d e f a u l t V a l u e ; }) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 179 / 228 Getery i setery jQuery V Metody text() i html() pozwalają odczytać (lub ustawić) zawartość elementu w postaci czystego tekstu lub HTML. $"head title" ) . t e x t ( ) $ ( "p" ) . html ( ) $ ( "h1" ) . t e x t ( f u n c t i o n ( n , c u r r e n t ) { r e t u r n " Paragraf " + ( n+1) + " " + c u r r e n t } dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 180 / 228 Wstawianie i zastępowanie elementów z wykorzystaniem jQuery I Metoda append() umożliwia dodanie zawartości na końcu określonego elementem. Metoda prepen() umożliwia dodanie zawartości na początku określonego elementem. Metoda after() pozwala na dodanie zawartości za określonym elementem. Metoda before() pozwala na dodanie zawartości przed określonym elementem. Metoda replaceWith() pozwala na zastąpienie celu za pomocą wyspecyfikowanej zawartości. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 181 / 228 Wstawianie i zastępowanie elementów z wykorzystaniem jQuery II $ ( "# article " ) . append ( "<br /> Opublikowane :" + nick ) ; $ ( "p" ) . b e f o r e ( "<hr />" ) ; $ ( "p" ) . a f t e r ( "<hr />" ) ; $ ( "h1" ) . p r e p e n d ( " Rozdzia ł " ) ; $ ( "hr" ) . r e p l a c e W i t h ( "<br />" ) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 182 / 228 Ajax z wykorzystaniem jQuery I Biblioteka jQuery wprowadza szereg udogodnień do obsługi Ajax. Metoda load() - pobiera URL i asynchronicznie ładuje zawartość tego URL do wybranego elementu (zastępując starą zawartość nową). s e t I n t e r v a l ( function () { $ ( "# status " ) . l o a d ( " stats .html" ) ; } , 60000) ; Opcjonalnymi argumentami metody load są parametry dodatkowe dla wymaganego URL (są do niego dodawane) oraz funkcja wywołania zwrotnego (callback) wywołana w momencie zakończenia żądania (pozwala poznać status żądania). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 183 / 228 Ajax z wykorzystaniem jQuery II Funkcja jQuery.getScript() pozwala na pobranie i wykonanie kodu JavaScript w globalnym zasięgu. Funkcja jQuery.getJSON() umożliwia pobranie tekstu i przetworzenie go przed wywołaniem specjalnej funkcji wywołania zwrotnego. Funkcje jQuery.get() i jQuery.post() pobierają zawartość określonego URL-a i przekazują wynik do wyspecyfikowanej funkcji wywołania zwrotnego. Funkcja get() używa żądania GET a funkcja post() używa żądania POST. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 184 / 228 Ajax z wykorzystaniem jQuery III Najbardziej elastyczną funkcją jest jQuery.ajax(). Funkcja ta pozwala na przekazywanie obiektu z określonymi atrybutami, które specyfikują dokładnie żądanie. jQuery . a j a x ({ t y p e : "POST" , url : url , data : null , dataType : "json" , t i m e o u t : 5000 }) ; dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 185 / 228 jQuery UI Elementy wprowadzane przez jQuery stanowią ramę dla wielu pluginów. Jednym z nich jest jQuery Ui. Biblioteka ta wprowadza szereg kontrolek interfejsu użytkownika między innymi pola tekstowe z uzupełnianiem informacji, kontrolkę umożliwiającą wybór daty, paski postępu. Plugin jQuery UI implementuje także ogólne interakcje pozwalające na przeciąganie, zmianę rozmiaru, wybór i sortowanie dowolnego elementu dokumentu. Dodaje także efekty wizualne - ukrywanie, przejścia kolorów itp. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 186 / 228 Literatura 1 D.Flanagan ”JavaScript: The Definitive Guide” wydanie szóste, O’Reilly Media 2011 2 https://developer.mozilla.org/en-US/docs/Web/API 3 http://try.jquery.com 4 http://jqueryui.com/ 5 http://es6-features.org 6 https://github.com/lukehoban/es6features dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 187 / 228 Funkcje jako obiekty I Funkcje Pythona są obiektami. Mogą być przypisywane do innych zmiennych, przekazywane do innych funkcji, osadzane w strukturach danych, zwracane z funkcji. def k w a d r a t ( x ) : return x ∗ x def s z e s c i a n ( x ) : return x ∗ x ∗ x fun = kwadrat fun (12) l s t = [ ( kwadrat , 1 2 ) , ( s z e s c i a n , 1 0 ) ] for ( f , x ) in l s t : print f (x) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 188 / 228 Funkcje jako obiekty II def make ( f u n ) : def w y w o l a j ( x ) : return fun ( x ) return wywolaj f1 = wywolaj ( kwadrat ) f1 (12) f2 = wywolaj ( s z e s c i a n ) f2 (10) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 189 / 228 Funkcje jako obiekty III Funkcje posiadają własne atrybuty takie jak na przykład nazwa, dokumentacja domknięcie itp. def f u n c ( x ) : """ Funkcja podnosz ąca x do potęgi drugiej """ return x ∗ x print ( func . name ) print ( func . d o c ) print ( func . c l o s u r e print ( dir ( func ) ) dr inż. Andrzej Grosser ) Języki interpretowane Rok akademicki 2015/16 190 / 228 Funkcje jako obiekty IV Moduł doctest wyszukuje tekst, który wygląda jak interaktywna sesja Pythona a następnie wykonuje ten kod w celu zweryfikowania, że działa on dokładnie tak jak pokazano. Jest kilka sposobów użycia doctest: Do sprawdzenia, że docstringi modułu są nadal zgodne z tym co przykłady pokazują. Do wykonywania testów regresyjnych, które weryfikują czy interaktywne przykłady działają zgodnie ze spodziewanym. Do zapisu samouczka dla modułu, które pokazują jak on działa (wykonywalna dokumentacja). Do działania wymaga trybu gadatliwego (-v). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 191 / 228 Funkcje jako obiekty V def d o d a w a n i e ( x , y ) : """ Dodaje do siebie x i y >>> dodawanie (0, 4) 4 >>> dodawanie (5, 4) 9 >>> dodawanie (5, -5) 0 """ return x + y if name == " __main__ " : import d o c t e s t d o c t e s t . testmod ( ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 192 / 228 Funkcje jako obiekty VI $ python testy.py $ python testy.py -v Trying: dodawanie(0, 4) Expecting: 4 ok Trying: dodawanie(5, 4) Expecting: 9 ok dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 193 / 228 Funkcje jako obiekty VII Trying: dodawanie(5, -5) Expecting: 0 ok 1 items had no tests: __main__ 1 items passed all tests: 3 tests in __main__.dodawanie 3 tests in 2 items. 3 passed and 0 failed. Test passed. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 194 / 228 Funkcje jako obiekty VIII Podobnie jak zwykłe obiekty, funkcje mogą posiadać dodatkowe atrybuty: def f u n k c j a ( ) : pass f u n k c j a . poziom = 1 f u n k c j a . z a b e z p i e c z o n a = True Atrybuty funkcji są z reguły używane w wyspecjalizowanych dziedzinach zastosowań takich jak generatory parserów i szkielety aplikacji, gdzie dostarczają dodatkowych informacji o obiekcie funkcji. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 195 / 228 Funkcje jako obiekty IX Jest też możliwe stworzenie obiektu, który się będzie wywoływał jak funkcja. Do tego celu należy utworzyć w klasie metodę __call__ class Przyklad : def call ( self ) : p r i n t ( " Testowe wywołanie obiektu jako funkcji " ) obj = Przyklad () obj () dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 196 / 228 Operator lambda I Funkcje anonimowe w Pythonie tworzy się z wykorzystaniem wyrażenia lambda. Składnia wyrażenia lambda jest następująca: lambda argumenty: wyrazenie gdzie argumenty są listą zmiennych rozdzielonych przecinkami, zaś wyrażenie oznacza wyrażenie, które może korzystać z tych zmiennych. Wynikiem obliczenia wyrażenia lambda jest obiekt funkcyjny, który może być przypisany do zmiennej ( lambda x : x ∗ ∗ 2 ) ( 1 2 ) f u n = lambda x : x ∗∗2 fun (12) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 197 / 228 Operator lambda II Wyrażenia lambda w Pythonie są dość ograniczone nie można w nich korzystać z niektórych instrukcji (np. pętli) - dozwolone są jedynie wyrażenia. # Niepoprawne funkcje anonimowe lambda x : f o r i i n x : p r i n t ( i ) lambda x : i f x >0: 1 e l s e −1 #I jedna poprawna lambda x : 1 i f x>0 e l s e −1 Innymi słowy wyrażenia lambda są jak funkcje z pojedynczą instrukcją powrotu (return). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 198 / 228 Operator lambda III Wyrażenia lambda są użyteczne w sytuacji, gdy przekazywana funkcja ogranicza się do prostego obliczenia wyrażanie, nie jest wtedy potrzebne tworzenie pełnej definicji funkcji. def w y w o l a j F u n k c j e ( f , x ) : return f ( x ) w y w o l a j F u n k c j e ( lambda x : x ∗ ∗ 2 , 1 2 ) # inaczej konieczne def k w a d r a t ( x ) : r e t u r n x ∗∗2 w y w o l a j F u n k c j e ( kwadrat , 1 2 ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 199 / 228 Operator lambda IV Są również użyteczne, gdy użycie instrukcji (np. definicji funkcji) byłoby niepoprawne składniowo: l s t = [ lambda x : x , lambda x : x ∗∗ 2 , lambda x : x ∗∗ 3 ] print l s t [1](12) Definicja literału listowego zakłada użycie wyrażeń a nie instrukcji definicja funkcji jest, więc w tym przypadku niedozwolona i koniczne jest użycie wyrażeń lambda. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 200 / 228 Operator lambda V Wyrażenia lambda można zagnieżdżać - można wewnątrz definicji wyrażenia lambda użyć innego wyrażenia lambda. W zagnieżdżonych wyrażeniach można wykorzystywać argumenty przekazywane do wyrażenia (wyrażeń zewnętrznych) - zagnieżdżony zasięg funkcyjny. ( lambda x : ( lambda y : x + y ) ) ( 1 2 ) ( 4 ) #to samo co def u t w o r z D o d a j ( x ) : def f u n ( y ) : return x + y return fun utworzDodaj (12) (4) Trzeba jednak zachować ostrożność - takie zagnieżdżone konstrukcje bardzo zaciemniają kod. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 201 / 228 Narzędzia programowania funkcyjnego I Funkcja map pozwala na wywołanie określonej funkcji dla wszystkich elementów listy, krotki, słownika. Przyjmuje funkcję i listę (listy) (ogólnie coś co pozwala na przechodzenie po swoich elementach), zwraca listę. #[1, 4, 9, 16] map( lambda x : x ∗∗ 2 , [ 1 , 2 , 3 , 4 ] ) #[0, 3, 4, 3, 0] # range (5) -> [0, 1, 2, 3, 4] # range (4,-1,-1) -> [4, 3, 2, 1, 0] map( o p e r a t o r . mul , range ( 5 ) , range (4 , −1 , −1) ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 202 / 228 Narzędzia programowania funkcyjnego II Funkcja filter pozwala na odfiltrowanie z listy tylko tych elementów, dla których predykat (funkcja zwracająca wartość logiczną) zwraca wartość prawdy. Funkcja przyjmuje predykat i listę, zwraca listę. # Tylko elementy parzyste #[0, 2, 4, 6, 8] f i l t e r ( lambda x : x%2 == 0 , range ( 1 0 ) ) Zamiast wyrażenia lambda mógłby być przekazywany obiekt funkcyjny. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 203 / 228 Narzędzia programowania funkcyjnego III Funkcja reduce() - wywołuje dwuargumentową funkcję łącząc kolejne elementy listy od lewej do prawej, powoduje to zredukowanie listy do pojedynczej wartości. Przyjmuje funkcję, listę oraz opcjonalną wartość początkową. # Oblicza wartość # ((((1+2) +3) +4) +5) reduce ( lambda x , y : x+y , [ 1 , 2 , 3 , 4 , 5 ] ) # reduce ( operator .add , [1, 2, 3, 4, 5]) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 204 / 228 Narzędzia programowania funkcyjnego IV Funkcja zip() - zwraca listę krotek, w której każda i-ta krotka zawiera i-te elementy z sekwencji przekazywanych jako argumenty. Jeżeli są przekazywane listy o różnej długości to długość wyniku jest obcinana do najkrótszego argumentu. Z pojedynczym argumentem zwraca listę jednoelementowych krotek. x = [1 , 2 , 3 , 4] y = [5 , 6 , 7 , 8] #[(1 , 5), (2, 6) , (3, 7) , (4, 8)] zip (x , y ) #[(1 ,) , (2,), (3 ,) , (4 ,)] zip ( x ) #[(1 , 5, 1), (2, 6, 2) , (3, 7, 3) , (4, 8, 4)] z i p ( x , y , range ( 1 , 1 0 0 ) ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 205 / 228 Narzędzia programowania funkcyjnego V Funkcja partial z modułu functools umożliwia częściową aplikację funkcji, tworzy specjlany obiekt, który jest pośrednikiem do wywołania funkcji. Pozwala na ustalenie kilku argumentów funkcji w nowym obiekcie z uproszczoną sygnaturą. b a s e t w o = p a r t i a l ( i n t , b a s e =2) #nie 11 111 lecz 31 b a s e t w o ( ’11111 ’ ) # alternatywnie def b a s e t w o ( a r g ) : r e t u r n i n t ( arg , 2 ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 206 / 228 Dekoratory I Dekorator to funkcja, której głównym zadaniem jest przeźroczyste opakowanie innej funkcji lub klasy. Podstawowym celem tego zabiegu jest zmiana lub rozszerzenie zachowania opakowywanego obiektu. Dekoratory są lukrem syntaktycznym na wywołanie funkcji pobierającej funkcję. Dekoratory są oznaczane symbolem @. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 207 / 228 Dekoratory II @przyklad def f u n ( x ) : return x ∗ x ∗ x #jest równoważne def f u n ( x ) : return x ∗ x ∗ x fun = przyklad ( fun ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 208 / 228 Dekoratory III # Funkcja pomocnik dodaje elementy do wywołania # funkcji dekorowanej . # Funkcja przyklad zwraca obiekt tej funkcji . # Funkcja dekorowana jest wywołana poś rednio . def p r z y k l a d ( f ) : def pomocnik ( ∗ a r g s , ∗ ∗ k w a r g s ) : p r i n t ( "Wywołano " + f . n a m e ) r e t u r n f ( ∗ a r g s , ∗∗ k w a r g s ) r e t u r n pomocnik dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 209 / 228 Dekoratory IV Dekoratory łatwiej dostrzec niż wywołanie funkcji pomocniczej, która może być w kodzie oddalona od modyfikowanej funkcji lub klasy. Dekoratory są aplikowane raz, gdy jest definiowana klasa lub funkcja, nie ma potrzeby dodawania dodatkowego kodu dla każdego odwołania do funkcji lub klasy, które mogą się zmienić w przyszłości. Użytkownik rzadziej zapomina dostosować funkcji lub klasy do wymagań API. Z drugiej strony dekoratory wprowadzając opakowanie mogą zmieniać typy dekorowanych obiektów - może powodować dodatkowe narzuty związane z dodatkowymi wywołaniami. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 210 / 228 Dekoratory V Pojedynczą funkcję może dekorować wiele dekoratorów. Ma przy tym znaczenie kolejność dekorowania. @foo @bar @spam def f u n k c j a ( a r g ) : return arg + arg #jest to równowa żne def f u n k c j a ( a r g ) return arg + arg f u n k c j a = f o o ( b a r ( spam ( f u n k c j a ) ) ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 211 / 228 Dekoratory VI Dekorator trace, jeżeli jest włączony ślad, zapisuje informacje o wywołaniu funkcji w pliku debug.log. e n a b l e t r a c i n g = True if enable tracing : l o g = open ( " debug .log" , "w" ) def t r a c e ( f ) : if enable tracing : dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 212 / 228 Dekoratory VII @ f u n c t o o l s . wraps ( f ) def pomocnik ( ∗ a r g s , ∗∗ k w a r g s ) : l o g . w r i t e ( "Wywołanie {0} z argumentami {1} i {2}\n" . format ( f . n a m e , a r g s , k w a r g s ) ) w y n i k = f ( ∗ a r g s , ∗∗ k w a r g s ) l o g . w r i t e ( " Funkcja {0} zwróciła {1}\n" . format ( f . n a m e , w y n i k ) ) return wynik r e t u r n pomocnik else : return f dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 213 / 228 Dekoratory VIII @trace def f u n ( x ) : return x ∗ x ∗ x fun (10) fun (8) # Zawarto ść pliku debug .log #Wywołanie fun z argumentami (10 ,) i {} # Funkcja fun zwróciła 1000 #Wywołanie fun z argumentami (8 ,) i {} # Funkcja fun zwróciła 512 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 214 / 228 Dekoratory IX Dekorator memoize pozwala zapamiętać wyniki poprzednich wywołań funkcji - gdy nastąpi kolejne wywołanie z tymi argumentami funkcja nie będzie wywołana, a wynik zostanie pobrany ze słownika. def memoize ( o b j ) : c a c h e = o b j . c a c h e = {} @ f u n c t o o l s . wraps ( o b j ) def memoizer ( ∗ a r g s , ∗∗ k w a r g s ) : key = s t r ( a r g s ) + s t r ( kwargs ) i f k e y not i n c a c h e : c a c h e [ k e y ] = o b j ( ∗ a r g s , ∗∗ k w a r g s ) return cache [ key ] r e t u r n memoizer dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 215 / 228 Generatory I Generatory są funkcjami, które umożliwiają tworzenie sekwencji wartości, które mogą być używane do iterowania. Funkcje tego rodzaju używają słowa kluczowego yield do zwrotu kolejnych potrzebnych wartości. def s e k w e n c j a ( n ) : while n < 10: yield n n += 1 Po wywołaniu funkcji nie jest wykonywany kod, ale tworzony jest specjalny obiekt generatora. x = sekwencja (0) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 216 / 228 Generatory II Obiekt generatora jest wywołuje funkcję aż do słowa yield, gdy wywoływana jest metoda next() (__next__() w Python 3). Przy każdym kolejnym wywołaniu program jest wznawiany od pierwszej instrukcji po yield. x . next ( ) # 0 x . next ( ) # 1 itd aż do 10 Najczęściej obiekt generatora jest wykorzystywany w pętlach: for i in sekwencja (10) : print i ∗ i dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 217 / 228 Generatory III Sekwencja może być potencjalnie nieskończona: def s e k w e n c j a ( n ) : while t r u e : yield n n += 1 x = sekwencja (0) #0 x . next ( ) #x. __next__ () w Python 3 #1 x . next ( ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 218 / 228 Generatory IV Generatory umożliwiają funkcjom uniknięcie wykonywania całej pracy od razu, jest to szczególnie istotne, gdy tworzone listy są duże lub gdy przy tworzeniu listy dla każdego elementu jest wykonywane dużo obliczeń. Dodatkowo generatory stanowią prostszą alternatywę do ręcznego zapisywania stanu pomiędzy kolejnymi iteracjami - w generatorach zmienne osiągalne w zasięgu funkcji są zapisywane i przywracane automatycznie. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 219 / 228 Generatory V def fibNum ( n ) : currNum = 1 prevNum = 1 yield 1 i f n == 1 : return yield 1 i = 2 while i < n : prevNum , currNum = currNum , currNum + prevNum y i e l d currNum i += 1 dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 220 / 228 Generatory VI x = fibNum ( 3 ) # 1 next ( x ) # 1 next ( x ) # 2 next ( x ) # Traceback (most recent call last): # File "< pyshell #54 >" , line 1, in <module > # next(x) # StopIteration next ( x ) [ i f o r i i n fibNum ( 1 0 0 ) ] dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 221 / 228 Korutyny I Instrukcja yield może być również wywoływana po prawej stronie operatora przypisania. Funkcja, która używa yield w ten sposób jest nazywana korutyną (ang. coroutine). Do tak przygotowanej funkcji wysyła się kolejne wartości przy pomocy metody send(). Należy przy tym pamiętać o wcześniejszym wywołaniu metody next() - sterowanie przejdzie do pierwszej instrukcji yield. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 222 / 228 Korutyny II def o d b i o r c a ( ) : p r i n t "Gotów do odbioru :" w h i l e ( True ) : elem = ( y i e l d ) p r i n t elem //... o = odbiorca () o . next ( ) o . send (0) o . send (12) o . s e n d ( "Atom" ) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 223 / 228 Korutyny III Korutyna zazwyczaj może być uruchamiana bez końca, chyba że zostanie jawnie zamknięta lub kończy się. Do zamknięcia strumienia wartości wejściowych służy metoda close(): o . close () # Traceback (most recent call last): # File "<stdin >", line 1, in <module > # StopIteration o . send (43) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 224 / 228 Korutyny IV Korutyny mogą jednocześnie przyjmować i zwracać wartości, w sytuacji gdy wartość jest dostarczana w wyrażeniu yield. def p o t e g a ( ) : p r i n t "Gotów" wynik = 0 w h i l e ( True ) : elem = ( y i e l d w y n i k ) w y n i k = 2 ∗∗ elem dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 225 / 228 Korutyny V o = odbiorca () #Gotów #0 o . next ( ) #4096 o . send (12) #1024 o . send (10) Wywołanie metody next() spowoduje przejście do wyrażenia yield, które zwróci 0 (wartość początkowa zmiennej wynik). Wartość jaka jest zwracana przy kolejnych wywołaniach send() pochodzi z następnego wyrażenia yield. dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 226 / 228 Korutyny VI Z koniecznością wywołania metody next() można poradzić sobie tworząc odpowiedni dekorator. def c o r u t i n e ( f u n ) : def s t a r t ( ∗ a r g s , ∗∗ k w a r g s ) : g = f u n ( ∗ a r g s , ∗∗ k w a r g s ) g . next ( ) return g return s t a r t Dekorator automatycznie wykona niezbędne do prawidłowego działania korutyny wywołanie metody next(). dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 227 / 228 Korutyny VII @corutine def o d b i o r c a ( ) : p r i n t "Gotów do odbioru :" w h i l e ( True ) : elem = ( y i e l d ) p r i n t elem o = odbiorca #Nie zakończy się błędem o . send (1212) dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 228 / 228 Literatura 1 M. Lutz ”Learning Python” wydanie piąte, O’Reilly Media 2013 2 https://www.python.org/doc/ dr inż. Andrzej Grosser Języki interpretowane Rok akademicki 2015/16 229 / 228