14-pwjs-wyklad02-JS

Download Report

Transcript 14-pwjs-wyklad02-JS

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
[email protected]
http://wbieniec.kis.p.lodz.pl
Instytut Informatyki Stosowanej
Politechnika Łódzka
1
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ę
Manufacturers Association)
ECMA (European Computer
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.
4
DOM i BOM
BOM (Browser Object 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 skrypt możemy umieszczać w każdym pliku HTML. Odczytuje on odpowiednie
atrybuty pliku HTML i wyświetla datę.
Ustawienia monitora
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).
Pora dnia
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ę
<script type="text/javascript">
<!-var zmienna="Java Script";
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.
Nie musimy ich wcześniej definiować
ani przydzielać konkretnego typu,
jednak jest to możliwe.
Typy zmiennych:
boolean
char
float
var
byte
double
int
<HTML>
<HEAD></HEAD>
<BODY>
<SCRIPT language="JavaScript">
imie="Jacek ";
nazwisko="Kowalski";
tekst=imie+nazwisko;
document.write(tekst)
</SCRIPT>
</BODY>
</HTML>
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>
Obliczanie ilości sekund w dobie to proste mnożenie
(inne to analogicznie +,-,/) .
W zmiennej wynik znak + pozwala na łączenie ciągów znakowych
(konkatenacja)
Konstrukcje językowe
- instrukcje warunkowe
Konstrukcje językowe
-instrukcje warunkowe
Pętle
<P>Przykład: wypisywanie ciągu potęg liczby 2 w tabelce
<script>
document.write("<TABLE><TR>");//Tu tworzymy początek tabeli
liczba=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ą
onMouseMove
Ruch myszy nad obiektem
onDblClick
Podwójne kliknięcie
onMouseOver
Wjechanie myszy nad obiekt
onMouseOut
Zjechanie myszy z obiektu
onMouseDown Wciśnięcie przycisku
onMouseUp
Puszczenie przycisku
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
21
Metody rejestrowania zdarzeń
Rejestrowanie zdarzenia w sekcji skryptu
var element = 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">
function wypisz() {
alert('zostałem klikniety!');
}
document.getElementById('Przycisk').onclick = wypisz
</script>
Przykład 2 – z zastosowaniem funkcji anonimowej
document.getElementById('Przycisk').onclick = function() {
alert('zostałem klikniety!');
}
22
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()
23
Metody rejestrowania zdarzeń
Rejestrowanie zdarzenia z użyciem addEventListener. W ten sposób możemy podpiąć kilka
funkcji obsługujących zdarzenie
var element = 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
24
Rozszerzona obsługa zdarzeń
Polega na pobraniu wartości pseudoparametru funkcji obsługi zdarzenia
document.getElementById('Przycisk').onclick = function(evt) {
alert('Typ zdarzenia: ' + evt.type);
}
SrcElement
Element, który wywołał zdarzenie
type
returnValue
Typ zdarzenia
Określa, czy zdarzenie zostało odwołane
cancelBubble
clientX, clientY
Może odwołać kaskadowe wywołanie zdarzeń
Współrzędne kursora myszy (względem okna)
offsetX, offsetY
Współrzędne kursora myszy (względem elementu)
button
Czy wciśnięto jakiś przycisk myszy?
altKey, ctrlKey, shiftKey
Czy trzymano przyciski Alt, Ctrl lub Shift
keyCode
Wartość unicode wciśniętego klawisza
Wstrzymanie domyślnej akcji
element.addEventListener('click',function (e) {
alert('Ten link nigdzie nie przeniesie.');
e.preventDefault();
},false);
25
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
function stopBubble(e) {
if (!e) var e = 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);}
26
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 przez zdarzenia onBlur oraz onFocus powoduje zmianę atrybut value pola typu input.
W momencie kliknięcia w pole tekstowe sprawdzane jest czy wartość to "Szukaj..." (onfocus)
Jeśli tak to zmieniane jest to na puste.
W momencie ponownego kliknięcia gdzieś na stronie (poza polem tekstowym) sprawdzane jest
czy pole ma value puste - jeśli tak to ustawiane jest ono na "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?";
case 1: napis="To w zupełności wystarczy.";
case 2: napis="Jesteś maniakiem.";
default: napis="Powinieneś się leczyć";
}
Operatory:
< - mniejsze niż
!= - różne
> -większe niż
&& - koniunkcja
<= >= -mniejsze lub równe
|| - alternatywa
== - równe
! - negacja
break;
break;
break;
break;
Tablice i funkcje
Tak definiujemy
funkcję
Tak definiujemy
tablicę
Indeksujemy od 0
<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>
Wywołanie funkcji
jako reakcja na
zdarzenie
Formularze i tablice asocjacyjne
<script type="text/javascript">
<!-var ksiazka = new Array();
ksiazka["puste"] = "Wybierz osobę...";
ksiazka["Czesław"] = "697854954";
ksiazka["Gienek"] = "456345667";
ksiazka["Marianna"] = "0700434545";
function pokazNumer(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
function nazwa_funkcji(parametr1, parametr2,
instrukcje funkcji
}
. . . ,parametrn) {
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
var zm = new Function("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
35
Funkcja anonimowa - przykład
<!doctype HTML>
<HTML>
<body>
<script type="text/JavaScript">
var func = prompt("Wprowadź ciało funkcji");
var x = prompt("Wprowadź wartość argumentu x");
var y = prompt("Wprowadź wartość argumentu y");
var op = new Function("x", "y", func);
var wynik = 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.
36
Literały funkcji
var zm = function(par1, par2,
{
instrukcje funkcji
}
. . . ,parn)
Literały funkcji (inaczej wyrażenia funkcji ang. function expressions) 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
});
37
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.
var czyLiczba = function(x) {
var RegExp = /^(-)?(\d+)$/;
return String(x).match(RegExp);
}
var tab1 = [1,2,3,4,5,6,7,8,9,0];
var tab2 = [1,2,3,4,5,6,7,8,9,'zero'];
document.writeln(tab1.every(czyLiczba));
document.writeln(tab2.every(czyLiczba));
document.writeln(tab2.some(czyLiczba));
document.writeln(tab2.filter(czyLiczba));
//
//
//
//
true
false
true
[1,2,3,4,5,6,7,8,9]
38
Funkcje zagnieżdżone i domknięcia
function zewnetrzna(argumenty){
function wewnetrzna(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){
var wykrzyknik = "!";
function dajTekst(tekst2){
return tekst1 + " " + tekst2 + wykrzyknik;
}
return dajTekst;
}
var zm1 = komunikat("Witaj"); //utworzenie obiektu funkcji wewnę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)
39
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)
function dodaj_wiele() {
var wynik = 0;
for(i in arguments) {
wynik += arguments[i];
}
return wynik;
}
dodaj_wiele(1, 2, 3, 4, 5); //zwróci 15
40
Definiowanie i używanie obiektów
Przy definiowaniu obiektów JavaScript używa się notacji JSON.
Można wtedy pominąć cudzysłowie przy kluczu.
var obj = {
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"
41
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.
42
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„
43
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 = new osoba.constructor("Adam", "Małysz", 35);
44
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 instanceof Object; //zwróci true
osoba instanceof Osoba; //zwróci true
osoba instanceof Array; //zwróci false
typeof osoba; //zwróci "object"
var arr = [1, 2, 3];
arr instanceof Array; //zwróci true
typeof arr; //zwróci "object"
typeof 2; //zwróci "number"
45
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
46
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 in this) {
if(this[i] === element)
return true;
}
return false;
}
var tab = [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
47
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() {return this.nazwa; }
}
function Figura2D() {
this.nazwa = 'figura2D';
}
Figura2D.prototype = new Figura();
Figura2D.prototype.constructor = Figura2D;
function Trojkat(bok, wysokosc) {
this.nazwa = 'trojkat';
this.bok = bok;
this.wysokosc = wysokosc;
this.pobierzPole = function() {
return this.bok * this.wysokosc * 0.5;
}
}
Trojkat.prototype = new Figura2D();
Trojkat.prototype.constructor = Trojkat;
48
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() { return this.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
49