490 likes | 745 Views
Programowanie w językach skryptowych. Wykład 2: JavaScript – programowanie oparte o funkcje. Materiały źródłowe: Shelley Powers : " JavaScript . Wprowadzenie " Stoyan Stefanov " JavaScript . Programowanie obiektowe ". Opracował: dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl
E N D
Programowanie w językach skryptowych Wykład 2: JavaScript – programowanie oparte o funkcje Materiały źródłowe: Shelley Powers: "JavaScript. Wprowadzenie" StoyanStefanov "JavaScript. Programowanie obiektowe" Opracował: dr inż. Wojciech Bieniecki wbieniec@kis.p.lodz.pl http://wbieniec.kis.p.lodz.pl Instytut Informatyki Stosowanej Politechnika Łódzka
JavaScript JavaScript jest to język skryptowy dla dokumentów internetowych (od 1995). Skrypty napisane za pomocą JavaScript mogą być umieszczane na stronach WWW. Dzięki temu językowi można np. uzależnić wykonanie jakiejś instrukcji od reakcji osoby przeglądającej daną stronę. JavaScript ma też szerokie zastosowanie w tworzeniu formularzy. Umożliwia wnikanie w ich treści i sprawdzanie poprawności wypełnienia poszczególnych pól czy zaznaczenie odpowiednich opcji. Uwaga: nie istnieje standard JavaScript, tylko określona specyfikacja. Pisanie programów wymaga przetestowania działania skryptu na różnych przeglądarkach Tworzeniem specyfikacji zajmuje się ECMA (European Computer ManufacturersAssociation)
Cechy języka JavaScript Jest językiem prototypowym (odmiana obiektowości) Jest językiem dynamicznym Jest językiem słabo typowanym Posiada też cechy języka funkcyjnego Rozróżnia wielkość liter (jest case-sensitive). Posiada konstrukcje sterujące identyczne z tymi znanymi z języków Java i C++
Obiektowy model dokumentu Sposób przedstawienia obiektów, z których składa się dokument i relacji między nimi. DOM W3C służy głównie do przedstawienia dokumentów HTML oraz XML. Używają go języki CSS i JavaScript do operowania na dokumentach. Wg W3C DOM dokument to drzewiasty zbiór węzłów. Węzeł może być elementem, ciągiem tekstu, komentarzem, itp. Każdy węzeł może mieć jednego rodzica, dowolną ilość braci i, jeśli jest elementem, dowolną ilość dzieci.
DOM i BOM BOM (BrowserObject Model) to zbiór obiektów dających dostęp do przeglądarki i ekranu. Najważniejszy obiekt to window – obiekt globalny. Wszystkie zmienne globalne stają się polami tego obiektu. Tworząc nową zmienną globalną zm, tak naprawdę tworzy się zmienną window.zm. Obiekt window zawiera w sobie następujące obiekty navigator – obiekt przechowujący informacje o przeglądarce i jej możliwościach location – obiekt przechowujący informację o adresie URL aktualnie załadowanej strony history – obiekt dający dostęp do stron odwiedzanych wcześniej w ramach tej samej sesji przeglądarki, frames – przechowuje zbiór ramek z bieżącej strony (iframes) screen – zawiera informacje na temat ustawień monitora (rozdzielczości, głębi kolorów) oraz o rozmiarze okna przeglądarki document – obiekt związany z aktualnie załadowanym dokumentem. Zawiera w sobie obiekty z DOM Pola i metody DOM umożliwiają dostęp i modyfikację wszystkich elementów strony
Przykłady użycia BOM Przeglądarka – navigator navigator.appName – nazwa przeglądarki navigator.platform – system operacyjny navigator.language – język przeglądarki Okno przeglądarki – window window.status="Wciśnij mnie" – zmiana paska statusu window.print() – wydrukowanie zawartości okienka window.close() – zamknięcie okienka przeglądarki window.frames["menu"] – odwołanie się do ramki o nazwie menu. window.history.back() – przejście do poprzedniej strony window.outerwidth – szerokość okienka w pixelach Dokument – czyli plik HTML – document document.lastModified() – zwraca datę ostatniej modyfikacji document.images["muzyka"] – odwołanie do obrazka o nazwie muzyka document.write("<B>"+document.lastModified()+"</B>") – wypisanie daty modyfikacji document.location.href="index2.html" – załadowanie nowej strony
Data ostatniej modyfikacji Ten skryptmożemyumieszczać w każdympliku HTML. Odczytuje on odpowiednieatrybutypliku HTML iwyświetladatę. Ustawieniamonitora Ten skrypt bada ustawienia rozdzielczości ekranu i ilość kolorów
Pozycja pliku w przeglądarce Skrypt ten pobiera adres URL załadowanego dokumentu HTML. W tym przykładzie adres ten jest wyświetlany w okienku formularza, ale skrypt ten może zabezpieczać przed uruchomieniem strony po jej ściągnięciu na dysk lokalny (musimy sprawdzić, czy plik rzeczywiście jest tam, gdzie powinien).
Umieszczanie skryptów JS: <HTML> <BODY> <SCRIPT type="text/javascript"> document.write("<B>Ten tekst został napisany dzięki JavaScript</B>") </SCRIPT> Ten zaś został napisany w HTML-u </BODY> </HTML> <SCRIPT type="text/javascript" src="programik.js"> </SCRIPT> • znacznik <script> możemy umieszczać wielokrotnie w dowolnym miejscu pliku HTML (najczęściej w sekcji HEAD) • kod źródłowy skryptu można umieścić w osobnym pliku z rozszerzeniem .js • Uwaga: skrypt wykonuje się od razu po załadowaniu dokumentu!
Umieszczanie skryptów JS: <SCRIPT type="text/javascript"> //To jest zalecany sposób umieszczania skryptu </SCRIPT> <SCRIPT language="JavaScript"> //Sposób niezalecany </SCRIPT> <SCRIPT type="text/javascript" language="JavaScript1.5"> /*zadeklarowanie wykorzystywanej wersji JS - tutaj deklarujemy standard ECMAScript 3, czyli inaczej JavaScript 1.5 - tak informujemy przeglądarkę, że ma uruchamiać skrypt tylko jeśli obsługuje tą wersję*/ </SCRIPT>
JS i stare przeglądarki Starsze przeglądarki mogą sobie nie radzić z JS - dlatego stosuje się sztuczkę <scripttype="text/javascript"> <!-- varzmienna="JavaScript"; alert("Witaj"+zmienna); //--> </script> stara przeglądarka nie rozpozna znacznika <script> ale zobaczy komentarze <!--, więc zignoruje cały kod między tymi znacznikami. nowa przeglądarka zobaczy znak komentarza <!-- ale dla JS znak ten oznacza komentarz tylko w 1 linii, więc tę linię zignoruje, ale wykona kod JS będący w linijkach niżej. Zamykający znacznik komentarza --> jest dodatkowo komentarzem JS (//), bo inaczej byłby błędem dla JS, a musi on być po to, aby stara przeglądarka rozpoznała gdzie kończy się blok komentarza, który pomija.
Zmienne Zmienne używamy podobnie jak w innych językach skryptowych. <HTML><HEAD></HEAD><BODY><SCRIPT language="JavaScript"> imie="Jacek "; nazwisko="Kowalski"; tekst=imie+nazwisko; document.write(tekst) </SCRIPT></BODY></HTML> Nie musimy ich wcześniej definiować ani przydzielać konkretnego typu, jednak jest to możliwe. Typy zmiennych: booleanbyte char double floatint var Nazwy zmiennych Pierwsza litera nazwy musi być literą, podkreśleniem lub znakiem dolara. Nie używamy w nazwach spacji Wielkość znaków w nazwach ma znaczenie. Zaleca się korzystać w nazwach tylko z małych liter. Nie wolno korzystać ze słów zastrzeżonych - na przykład słowa var
Działania na zmiennych <script type="text/javascript"> var sek=60; var min=60; var godz=24; var sekundy_w_dniu= sek * min * godz; var napis1="1 dzień składa się z:"; var napis2=" sekund"; var wynik=napis1+sekundy_w_dniu+napis2; alert(wynik); </script> Obliczanieilościsekund w dobie to prostemnożenie (inne to analogicznie +,-,/) . W zmiennejwynikznak + pozwalanałączenieciągówznakowych (konkatenacja)
Pętle <P>Przykład: wypisywanie ciągu potęg liczby 2 w tabelce <script>document.write("<TABLE><TR>");//Tu tworzymy początek tabeliliczba=1;licznik=1;for(licznik;licznik<=10;licznik++){ liczba*=2;//Liczbę podwajamy document.write("<TD>"+liczba+"</TD>");}document.write("</TR></TABLE>");</script> Inne pętle – analogicznie jak w języku C, Java, PHP while(warunek) { ciąg_wyrażeń; } do { ciąg_wyrażen; }while(warunek);
Okienka dialogowe: <FORM><INPUT type="button" value="Pokaż adres strony„onClick="alert('Jesteś na stronie:'+document.URL);"> <P><INPUT type="button" value="Zamknij to okno"onClick="if (confirm('Czy na pewno tego chcesz?')) { window.close() }";> <P><INPUT type="button" value="Połącz się...„onClick="adres=prompt('Wprowadź adres strony','http://www.onet.pl'); if (adres!=null){location.href=adres}"></FORM> alert – okienko informacyjne (message box) confirm – okienko pytające (zwraca true lub false) prompt – wprowadzanie danych (input box)
Obsługa zdarzeń <a href="doc.html" onMouseOver="document.status='Clik Me'; return true"> Dokument </a> Zdarzenia związane z myszą: onClick Kliknięcie myszą onDblClick Podwójne kliknięcie onMouseDown Wciśnięcie przycisku onMouseUp Puszczenie przycisku onMouseMove Ruch myszy nad obiektem onMouseOver Wjechanie myszy nad obiekt onMouseOut Zjechanie myszy z obiektu Zdarzenia związane z klawiaturą: onKeyDown Wciśnięcie przycisku onKeyUp Puszczenie przycisku onKeyPress Naciśnięcie i zwolnienie przycisku
Zdarzenie onClick Umożliwia korzystanie z przycisku BUTTON <INPUT TYPE="BUTTON" OnClick="document.location.href='http://www.kis.p.lodz.pl'" VALUE="Powrot do strony glownej KIS"> Ostrzeżenie o działaniu linku <A HREF="http://www.kis.p.lodz.pl" OnClick="alert('Dokument otworzy sie w nowym okienku')" target="_blank"> Strona główna</a> Potwierdzenie kliknięcia linku <A HREF="http://www.kis.p.lodz.pl/usun.php" OnClick="return confirm('czy chcesz wykonać tę operację?')" > Usun plik</a>
Metody rejestrowania zdarzeń Rejestrowanie zdarzenia inline polega na określeniu zdarzenia wewnątrz znacznika. <a href="strona.html" onclick="alert(' Kliknąłeś! ')">kliknij</a> • Wady: • Mieszanie skryptów JS z kodem HTML (podobnie jak wpisane CSS) • rozwiązanie nie jest obiektowe – wewnątrz funkcji nie mamy dostępu do this czyli właściwości obiektu, na którym wywołano zdarzenie
Metody rejestrowania zdarzeń Rejestrowanie zdarzenia w sekcji skryptu varelement = document.getElementById('Przycisk'); element.onclick = funkcja1; element2.onmouseover = funkcja2; Przykład 1 – z zastosowaniem funkcji nazwanej <input type="button"id="Przycisk"value="kliknij"/> <script type="text/javascript"> functionwypisz() { alert('zostałemklikniety!'); } document.getElementById('Przycisk').onclick = wypisz </script> Przykład 2 – z zastosowaniem funkcji anonimowej document.getElementById('Przycisk').onclick = function() { alert('zostałemklikniety!'); }
Metody rejestrowania zdarzeń Rejestrowanie zdarzenia w sekcji skryptu dla wielu obiektów var akapity = document.getElementsByTagName('p'); for (i=0; i<akapity.length; i++) { akapity[i].onclick = function () { this.style.color = 'red'; } } Poza rejestrowaniem zdarzeń dla elementów, możemy też takie zdarzenia wywołać z innego miejsca w JS document.getElementById('Akapit1').onclick()
Metody rejestrowania zdarzeń Rejestrowanie zdarzenia z użyciem addEventListener. W ten sposób możemy podpiąć kilka funkcji obsługujących zdarzenie varelement = document.getElementById('Przycisk'); element.addEventListener('click', startDragDrop, false); element.addEventListener('click', wypiszCos, false); element.addEventListener('click', function() {this.style.color = 'red';}, false); Ta metoda pozwala również usuwać obsługę zdarzeń przy pomocy removeEventListener element.removeEventListener('click', startDragDrop, false); element.removeEventListener('click', wypiszCos, false); Metoda removeEventListener nie będzie działała dla funkcji anonimowej
Rozszerzona obsługa zdarzeń Polega na pobraniu wartości pseudoparametru funkcji obsługi zdarzenia document.getElementById('Przycisk').onclick = function(evt) { alert('Typzdarzenia: '+ evt.type); } Wstrzymanie domyślnej akcji element.addEventListener('click',function(e) { alert('Ten link nigdzienieprzeniesie.'); e.preventDefault(); },false);
Bąbelki - Kaskadowe wykonywanie zdarzeń Załóżmy istnienie zagnieżdżonych bloków <div style="..."id="blok1">1 <div style="..." id="blok2">2 <div style="..." id="blok3">3</div> </div> </div> <script type="text/javascript"> document.getElementById('blok1').onclick = function() { alert('Kliknąłeśmnie!')}; </script> Kliknięcie w element wewnętrzny powoduje po wykonaniu zdarzenia przesłanie go do elementu otaczającego (tu zawsze wywoła się alert) Wyłączenie tego zjawiska realizujemy poprzez funkcję stopPropagation functionstopBubble(e) { if(!e) vare = window.event; e.cancelBubble = true; if(e.stopPropagation) e.stopPropagation(); } document.getElementById('blok31').onclick = function() {alert('Kliknąłeśmnie!')} document.getElementById('blok32').onclick = function(e){stopBubble(e);} document.getElementById('blok33').onclick = function(e){stopBubble(e);}
Przykłady: Pole tekstowe Szukaj <FORM METHOD="POST"> <input type="text" name="search" value="Szukaj..." onblur="if(this.value=='') this.value='Szukaj...';" onfocus="if(this.value=='Szukaj...') this.value='';"/> <input type="submit" VALUE="Szukaj!"> </FORM> JS przezzdarzeniaonBlurorazonFocuspowodujezmianęatrybut value polatypu input. W momenciekliknięcia w pole tekstowesprawdzane jest czywartość to "Szukaj..." (onfocus) Jeślitak to zmieniane jest to napuste. W momencieponownegokliknięciagdzieśnastronie (pozapolemtekstowym) sprawdzane jest czy pole ma value puste - jeślitak to ustawiane jest onona "Szukaj..." .
Zdarzenie onSubmit <FORM action="index.html" method="POST" id="formularz" onSubmit="return waliduj();"> ... Tu występują pola formularza <INPUT type="submit" value="Wyślij"> </FORM> W ten sposób uruchamiamy funkcję waliduj() przed wysłaniem danych. Jeżeli zwróci ona true to formularz zostanie wysłany
Formularz – quiz <script type="text/javascript"> <!-- function obslugaFormularza() { var punkty = 0; if (window.document.quiz.pytanie1.checked == true){ punkty = punkty+1; } else { window.document.quiz.pytanie1.checked = true; punkty = punkty-1; } if (window.document.quiz.pytanie2.checked == true){ punkty = punkty+1; } else { window.document.quiz.pytanie2.checked = true; punkty = punkty-1; } if (window.document.quiz.pytanie3.checked == false){ punkty = punkty+1; } else { window.document.quiz.pytanie3.checked = false; punkty = punkty-1; } alert("Zdobyles "+punkty+ "punktów na 3 możliwe! Poprawne odpowiedzi zostaly przedstawione na ekranie!"); } //--> </script>
Formularz - quiz <form name="quiz"> <input type="checkbox" name="pytanie1"/>2+2 wynosi 4<br/> <input type="checkbox" name="pytanie2"/>To jest Kurs JavaScript<br/> <input type="checkbox" name="pytanie3"/>Maciek to imię żeńskie<br/> <input type="submit" value="Go!" onclick="obslugaFormularza(); return false;" /> </form>
Instrukcje warunkowe godz=(prompt("ile godzin spędzasz na czacie?")); switch(godz) { case 0: napis="Nie wiesz co to jest?"; break; case 1: napis="To w zupełności wystarczy."; break; case 2: napis="Jesteś maniakiem."; break; default: napis="Powinieneś się leczyć"; break; } Operatory: < - mniejsze niż > -większe niż <= >= -mniejsze lub równe == - równe != - różne && - koniunkcja || - alternatywa ! - negacja
Tablice i funkcje Tak definiujemy funkcję Tak definiujemy tablicę Indeksujemy od 0 Wywołanie funkcji jako reakcja na zdarzenie <SCRIPT language="JavaScript">function sortuj(){ wyraz=new Array(); wyraz[0]=document.forms["wyrazy"].wyr1.value; wyraz[1]=document.forms["wyrazy"].wyr2.value; wyraz[2]=document.forms["wyrazy"].wyr3.value; wyraz.sort(); alfab=wyraz[0]+" "+wyraz[1]+" "+wyraz[2]; document.forms["wyrazy"].posortowane.value=alfab; }</SCRIPT> <FORM name="wyrazy"> Wpisz w te pola jakieś wyrazy.<BR> <INPUT type="text" size="10" name="wyr1"> <INPUT type="text" size="10" name="wyr2"> <INPUT type="text" size="10" name="wyr3"><P><INPUT type="button" value="Gotowe" onClick="sortuj()"> <P>Wyrazy te w kolejności alfabetycznej:<BR> <INPUT type="text" size="50" name="posortowane"></FORM>
Formularze i tablice asocjacyjne <scripttype="text/javascript"> <!-- varksiazka = newArray(); ksiazka["puste"] = "Wybierz osobę..."; ksiazka["Czesław"] = "697854954"; ksiazka["Gienek"] = "456345667"; ksiazka["Marianna"] = "0700434545"; functionpokazNumer(tablica_z_ksiazka,osoba) { window.document.formularz.numer.value = tablica_z_ksiazka[osoba]; } //--> </script>
Formularze i tablice asocjacyjne <form name="formularz"> Osoba :<br/> <select onchange="pokazNumer(ksiazka,this.options[this.selectedIndex].value);"> <option value="puste">--Wybierz osobę--</option> <option value="Czesław">Czesiek</option> <option value="Gienek">Gienio</option> <option value="Marianna">Marianna</option> </select> <br/>NUMER :<br/> <input type="text" name="numer" value="Wybierz osobę..."/> </form>
Sposoby definiowania funkcji Funkcje deklaratywne functionnazwa_funkcji(parametr1, parametr2, . . . ,parametrn) { instrukcje funkcji } Funkcja deklaratywna jest analizowana składniowo tylko raz kiedy strona jest ładowana a wynik tej analizy jest wykorzystywany za każdym razem, gdy funkcja jest wywoływana. Funkcja posiada nazwę pod którą jest dostępna. Funkcje anonimowe varzm = newFunction("par1", "par2", . . . ,"parn", "cialo funkcji"); W JS funkcje są obiektami. Mogą być tworzone za pomocą konstruktora. Funkcja taka jest przetwarzana przez analizator składniowy za każdym razem, kiedy jest wywoływana. Dlatego też zawartość ciała funkcji może być dynamiczna
Funkcja anonimowa - przykład <!doctype HTML> <HTML> <body> <script type="text/JavaScript"> varfunc = prompt("Wprowadźciałofunkcji"); var x = prompt("Wprowadźwartośćargumentu x"); var y = prompt("Wprowadźwartośćargumentu y"); var op = new Function("x", "y", func); varwynik = op(x, y); alert("wynikiem jest wartość " + wynik); </script> </body> </html> Nie poleca się zezwalania odwiedzającym strony internetowe na definiowanie własnych funkcji na naszych stronach.
Literały funkcji varzm = function(par1, par2, . . . ,parn) { instrukcje funkcji } Literały funkcji (inaczej wyrażenia funkcji ang. functionexpressions) są utworzone wewnątrz innej instrukcji jako część wyrażenia. Są one przetwarzane przez analizator składniowy tylko raz, są statyczne, mogą otrzymać nazwę (ale nie muszą). Jeśli funkcja zostanie nazwana, jej nazwa jest dostępna tylko wewnątrz bloku, w którym jest zdefiniowana. function f1(x, y, z) { alert(z(x,y)); } f1(3, 2, function(x,y){ return x*y });
Funkcje zwrotne Istnieją metody zależne od funkcji, które są wywoływane automatycznie w oparciu o jakieś zdarzenie. Dla obiektu Array są to filter, forEach, every, map, some. Przykłady zastosowania: every – funkcja przegląda każdy element tablicy wywołując na nim funkcję zwrotną, dopóki funkcja nie zwróci false. some – zwróci prawdę, jeśli dla chociaż jednego z elementów funkcja zwrotna da true. filter – tworzy tablicę składającą się z elementów, dla których funkcja zwrotna daje true. varczyLiczba = function(x) { varRegExp = /^(-)?(\d+)$/; return String(x).match(RegExp); } vartab1 = [1,2,3,4,5,6,7,8,9,0]; vartab2 = [1,2,3,4,5,6,7,8,9,'zero']; document.writeln(tab1.every(czyLiczba)); // true document.writeln(tab2.every(czyLiczba)); // false document.writeln(tab2.some(czyLiczba)); // true document.writeln(tab2.filter(czyLiczba)); // [1,2,3,4,5,6,7,8,9]
Funkcje zagnieżdżone i domknięcia functionzewnetrzna(argumenty){ functionwewnetrzna(argumenty){ Instrukcje funkcji wewnetrznej } } Funkcja wewnętrzna może wykorzystywać niektóre argumenty funkcji zewnętrznej oraz jej zmienne. Funkcja zewnętrzna może też zwracać obiekt funkcji wewnętrznej function komunikat(tekst1){ varwykrzyknik = "!"; function dajTekst(tekst2){ return tekst1 + " " + tekst2 + wykrzyknik; } return dajTekst; } var zm1 = komunikat("Witaj"); //utworzenieobiektufunkcjiwewnętrznej var zm2 = zm1("świecie"); // fun.wewn. ma dostęp do zm.fun.zewn. alert(zm2); var zm3 = zm1("Studencie!");// fun.wewn.nadal ma dostęp do zm.fun.zewn. alert(zm3); Zwrócenie literału funkcji utworzonego jako obiekt wewnętrzny i przypisanie go do zmiennej nazywa się domknięciem (ang. closure)
Zmienna liczba parametrów Funkcje można wywoływać z dowolną liczbą argumentów, a nie z taką, z jaką zadeklarowano, że przyjmuje. W chwili wywołania w funkcji dostępny jest obiekt arguments, który zawiera wszystkie parametry wywołania. Jeżeli funkcja zostanie wywołana z mniejszą ilością argumentów niż zadeklarowano, to przyjmą one wartość null function dodaj(a, b) { alert(arguments.length); return a + b; } dodaj(2, 3, 4, 5); //wyświetli 4 (bo 4 argumenty), zwróci wynik 5 dodaj(1); //wyświetli 1, zwróci wynik NaN (bo 1 + null == NaN) functiondodaj_wiele() { var wynik = 0; for(i inarguments) { wynik += arguments[i]; } return wynik; } dodaj_wiele(1, 2, 3, 4, 5); //zwróci 15
Definiowanie i używanie obiektów Przy definiowaniu obiektów JavaScript używa się notacji JSON. Można wtedy pominąć cudzysłowie przy kluczu. varobj = { imie: 'Adam', nazwisko: 'Kwiatkowski', technologie: ['ExtJS', 'JavaScript', 'HTML5'] }; Dostęp do pół obiektów uzyskuje się przy pomocy operatora kropki lub indeksowania jak przy tablicy asocjacyjnej. alert(obj.imie); alert(obj['imie']); Po elementach obiektu można iterować używając for var obiekt = { imie: 'Anna', nazwisko: 'Nowak', wydzial: 'EEIA' }; for(pole in obiekt) { alert(pole); } //Wyświetli: "imie", "nazwisko", "wydzial" for(pole in obiekt) { alert(obiekt[pole]); } //Wyświetli: "Anna", "Nowak", "EEIA"
Właściwości obiektów JS Każdy typ zmiennych jest obiektem Funkcja również jest obiektem Wbudowane w JavaScript typy to: Object, Array, Function, Boolean, Number, String, Math, Date, RegExp oraz Error W języku większość typów jest typami referencyjnymi. Typami prostymi są: Number, Boolean i String W obiektach można definiować metody Dostęp do metod odbywa się tak samo jak dostęp do zwykłych pól: przy użyciu notacji z kropką lub notacji nawiasowej. Metody wywołuje się jak inne funkcje. W języku występuje słowo kluczowe this, które wskazuje na obiekt w kontekście którego została wywołana funkcja.
Metody Każda funkcja, jako że jest obiektem, zawiera też metody. Jedną z najważniejszych jest metoda call. Przyjmuje ona jako pierwszy argument obiekt, na rzecz którego ma zostać wywołana. Po pierwszym parametrze, podajemy argumenty, które normalnie przyjmuje funkcja, na rzecz której wywołano metodę call. var obj = { nazwa: 'obiekt', wyswietl: function() { alert("Jestem " + this.nazwa); } } var fun = function(arg) { alert("Nazwa: " + this.nazwa + ", arg:" + arg); } obj.wyswietl(); //wyświetli "Jestem obiekt" fun.call(obj, "parametr"); //wyświetli "Nazwa: obiekt, arg: parametr„
Konstruktory W JavaScript obiekty można tworzyć przy użyciu funkcji nazwanych konstruktorami. Pozwalają one tworzyć obiekty własnych typów. Przy pomocy konstruktorów można tworzyć własne „klasy”, mimo, że język nie definiuje słowa kluczowego class. Konstruktor wywołuje się przy pomocy operatora new. function Osoba(imie, nazwisko, wiek) { this.imie = imie; this.nazwisko = nazwisko; this.wiek = wiek; this.przedstawSie = function(ktos) { alert('Cześć ' + ktos + ', nazywam się ' +this.imie + ' ' + this.nazwisko + ' i mam ' + this.wiek + ' lat!'); }; } var osoba = new Osoba("Jan", "Kowalski", 30); osoba.przedstawSie("Adam"); W czasie gdy obiekt jest tworzony, otrzymuje on specjalne pole o nazwie constructor. Zawiera ono referencję do konstruktora. Można więc za jego pomocą tworzyć nowe obiekty danego typu. var osoba2 = newosoba.constructor("Adam", "Małysz", 35);
Instanceof i typeof Operator instanceof służy do sprawdzania, czy dany obiekt został utworzony danym konstruktorem. Operator typeof, zwraca typ obiektu. Operator dla prawie wszystkich typów zwraca wartość „object”, prócz dla Number, String, Boolean, Function i wartości undefined. osoba instanceofObject; //zwróci true osoba instanceof Osoba; //zwróci true osoba instanceofArray; //zwróci false typeof osoba; //zwróci "object" vararr = [1, 2, 3]; arrinstanceofArray; //zwróci true typeofarr; //zwróci "object" typeof 2; //zwróci "number"
Prototypy Obiekty funkcyjne posiadają pole prototype. Tworzone jest ono automatycznie w czasie definicji funkcji. Domyślną wartością jest pusty obiekt. Dodanie nowych pól i metod do prototypu nie wpłynie na działanie funkcji. Zostaną one użyte tylko podczas wywołania funkcji jako konstruktora i będą dodane do nowo tworzonego obiektu function Student(imie, nazwisko, indeks) { this.imie = imie; this.nazwisko = nazwisko; this.indeks = indeks; } Student.prototype.mow = function() { alert("Cześć, jestem " + this.imie); } Student.prototype.ocena = 5; var s = new Student("Jan", "Kowalski", 12345); s.mow(); //wyświetli "Cześć, jestem Jan" alert(s.ocena); //wyświetli 5
Prototypy Dzięki prototypom możliwe jest dodawanie nowych funkcjonalności do typów wbudowanych. Przykład: Dodać do obiektów typu Array możliwość sprawdzenia wystąpienia elementu. Array.prototype.inArray = function(element) { for(var i inthis) { if(this[i] === element) returntrue; } returnfalse; } vartab = [1, 2, 3]; tab.inArray(2); //zwróci true tab.inArray(5); //zwróci false Każdy obiekt posiada metodę isPrototypeOf(). Zwraca ona informację o tym, czy obiekt jest prototypem innego. Array.prototype.isPrototypeOf(tab); //zwróci true
Dziedziczenie w JS W JS nie występuje słowo kluczowe class, mimo to można tworzyć własne typy przy pomocy konstruktorów i prototypów. Standardowym sposobem implementacji dziedziczenia, opisanym w standardzie ECMAScript jest tworzenie łańcucha prototypów. Polega to na przypisywaniu obiektu klasy bazowej do prototypu klasy dziedziczącej. function Figura() { this.nazwa = 'figura'; this.toString = function() {returnthis.nazwa; } } function Figura2D() { this.nazwa = 'figura2D'; } Figura2D.prototype = new Figura(); Figura2D.prototype.constructor = Figura2D; functionTrojkat(bok, wysokosc) { this.nazwa = 'trojkat'; this.bok = bok; this.wysokosc = wysokosc; this.pobierzPole = function() { returnthis.bok * this.wysokosc * 0.5; } } Trojkat.prototype = new Figura2D(); Trojkat.prototype.constructor = Trojkat;
Pożyczanie konstruktora Jeżeli istnieje potrzeba skopiowania funkcjonalności jakiejś klasy, jednak nie chcemy jej włączać do hierarchii dziedziczenia, można skorzystać z pożyczenia konstruktora. W konstruktorze klasy, która ma odziedziczyć funkcjonalność, należy wywołać konstruktor innej klasy. Tak rozszerzona klasa nie będzie instancją klasy od której pożyczyła funkcjonalność, będzie jednak posiadała jej pola i metody. Można wykonać pożyczanie konstruktora od wielu klas jednocześnie. function Figura() { this.nazwa = 'figura'; this.toString = function() { returnthis.nazwa; } } function Figura2D() { Figura.call(this); this.nazwa = 'figura2D'; } var f = new Figura2D(); f.toString(); //zwróci figura2D f instanceof Figura2D //zwróci true f instanceof Figura //zwróci false – nie ma dziedziczenia