Pewnie słyszeliście już nazwę „programowanie obiektowe”? Jeżeli jeszcze nie programowaliście obiektowo, to nie ma się co martwić – JavaScript właściwie cała opiera się na programowaniu obiektowym ;).
W waszych skryptach nieraz i nie dwa odwołujecie się do obiektów. Na przykład window, document, button itp. to typowe obiekty, które posiadają swoje metody i właściwości :).
Oczywiście jak i inne języki, tak i Javascript umożliwia tworzenie własnych obiektów. Początkowo może się wam wydawać, ze jest to nie za bardzo użyteczne (w końcu można większość rzeczy zrobić przy pomocy funkcji itp), ale gdy zaznajomicie się z obiektami na pewno zmienicie zdanie. Przede wszystkim obiekty dają nam ochronę danych. Dziwnie brzmi prawda? Na stronie nie raz tworzyłeś button. Każdy z nich ma np. metodę onclick, właściwość value itp. Nie ma żadnego konfliktu w skrypcie, mimo tego, że obiekty te mają metody i właściwości takie same jak ich „bracia”. Poza tym programowanie obiektowe jest najbardziej bliskie rzeczywistości. Zapraszam do lektury.
Tworzenie pojedynczego obiektu
Aby utworzyć nowy pojedynczy obiekt możemy skorzystamy z poniższej konstrukcji:
1
2
3
4
5
6
7
8
|
var obiekt_1 = { imie: "Marcin" , wzrost: 184, wypisz : function () { alert( this .imie) } } |
Nasz obiekt już na starcie posiada dwie ustalone właściwości – imie i wzrost, oraz jedną metodę, która wypisuje jego imię. Metoda taka jest zwykłą funkcją utworzoną w konstrukcji obiektu. Dostęp do niej ma tylko ten obiekt. Dzięki temu realizujemy podstawową funkcję obiektowości – dostęp do właściwości i metod ma tylko dany obiekt.
Zwróć uwagę, że każda właściwość i metoda jest od następnej oddzielona przecinkiem (jest on wymagany).
Aby odwołać się do danego obiektu z jego wnętrza stosujemy instrukcję this. Dzięki temu możemy w łatwy sposób wywoływać z wnętrza inne metody danego obiektu lub korzystać z jego właściwości:
1
2
3
4
5
6
7
8
9
10
11
|
var obiekt_1 = { liczba: 100, kwadrat : function () { return this .liczba * this .liczba }, wypisz : function () { alert( this .kwadrat()) } } obiekt_1.liczba = 200; obiekt_1.wypisz(); |
Gdy nasz obiekt już istnieje, możemy do niego dodawać nowe metody lub właściwości, tak samo jak to robimy normalnie dla obiektu window. Popatrz na kod:
1
2
3
4
5
6
7
8
|
x = 10; //jest równoznaczne z window.x = 10; pisz = function () {...} //jest równoznaczne z window.pisz = function () {...} |
Tak naprawdę deklarując zwykłe zmienne globalne i funkcje definiujemy po prostu właściwości i metody dla obiektu window. JS nie wymaga stosowania odwołania do window, więc praktycznie zawsze pomijamy to odwołanie.
Podobnie właściwości i metody możemy deklarować dla nowych obiektów:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
var obiekt_1 = { imie: "Marcin" , wzrost: 184, wypisz : function () { alert( this .imie) } } obiekt_1.waga = 73; //dodaliśmy nową właściwość obiekt_1.wypisz = function () {alert( 'Wzrost: ' + this .wzrost + ', waga: ' + this .waga)} //dodaliśmy nową metodę obiekt_1.wypisz(); //zwróci Wzrost: 184, waga: 73 |
Tworzenie obiektu za pomocą konstruktora
Powiedzmy, że zamiast pojedynczego obiektu chcemy utworzyć ich kilka. Każdy obiekt powinien posiadać jakieś właściwości i metody np. width, height i wypisz().
Aby utworzyć kilka podobnych obiektów posłużymy się klasą obiektu. Czym jest klasa? To rodzaj foremki, która opisuje nam jak będą wyglądać tworzone na jej podstawie nowe obiekty. W JS klasę tworzymy za pomocą zwykłej funkcji:
1
2
3
4
5
6
7
8
|
function _KlasaObiektu(_width,_height) { this .width = _width; this .height = _height; this .wypisz = function () { alert( this .width + 'x' + this .height) } } |
Od tej pory każdy utworzony obiekt na podstawie _KlasaObiektu() będzie miał ustawione właściwości width i height na podane w atrybutach, oraz metodę wypisz. Specyficzna nazwa tej klasy czyli zaczynająca się od _ i dużej litery to tylko mój estetyczny wymysł, by łatwo oddzielić co pełni rolę klasy, a co funkcji.
Aby utworzyć nowy obiekt na podstawie istniejącej klasy stosujemy instrukcję new:
1
2
3
4
5
6
7
8
|
var obiekt_1 = new _KlasaObiektu(200,100); var obiekt_2 = new _KlasaObiektu(300,200); obiekt_1.wypisz(); //wypisze 200x100 obiekt_2.width = 600; obiekt_2.wypisz() //wypisze 600x200 |
Usuwanie właściwości
Aby usunąć właściwość obiektu, skorzystamy z operatora delete:
1
2
3
4
5
6
7
8
9
10
11
|
var kubek = { kolor: 'zielony' , wielkosc: 'duzy' , cena: 'wielka' } kubek.cena = 'mala' ; //Usuwamy właściwość cena delete kubek.cena; |
instrukcja Prototype
Javascript udostępnia jeszcze jeden sposób deklarowania metod i właściwości dla klas obiektu. Skorzystamy tutaj z instrukcji prototype.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function _KlasaObiektu() { this .imie = 'Marcin' ; this .wzrost = 183 } _KlasaObiektu.prototype.pisz = function () { //funkcja która będzie metodą naszego obiektu document.write( this .imie + ' ma ' + this .wzrost + 'cm wzrostu.' ) } _KlasaObiektu.prototype.waga = 73; var obiekt_1 = new _KlasaObiektu(); obiekt_1.pisz(); document.write(obiekt_1.waga) //wypisze sie 73 |
W kodzie klasy nie deklarowaliśmy żadnych metod. Dopiero korzystając z instrukcji prototype dodaliśmy metodę pisz i właściwość waga do naszej klasy. Od tej pory każdy nowo utworzony obiekt będzie posiadał te dodatkowe właściwości i metody.
Instrukcja prototype przydaje się, gdy do danego obiektu np String czy Array chcemy dodać dodatkową funkcjonalność np:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
function mixuj() { var tekst = '' ; for ( var x=0; x< this .length; x++) { tekst += (x%2==0)? this .charAt(x).toUpperCase() : this .charAt(x).toLowerCase() } return tekst; } function pierwszaLiteraDuza() { return this .charAt(0).toUpperCase() + this .substr(1); } String.prototype.pierwszaDuza = pierwszaLiteraDuza; String.prototype.mix = mixuj; |
Od tej pory każdy nowy string (tekst) będzie miał te metody, dzięki której zamieni pierwszą literę na dużą oraz zmiksuje wielkość liter:
1
2
3
4
5
6
|
var tekst = "marcinek" ; alert(tekst.pierwszaDuza()) //wypisze Marcinek var tekst = "marcinek" ; alert(tekst.mix()) //wypisze mArCiNeK |
Obiekty nadrzędne
Przypuśćmy, że mamy obiekt w obiekcie:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
_KlasaObiektu = function () { this .imie = 'Marcin' ; this .wzrost = 183 this .guzik = null ; this .init = function () { this .guzik = document.createElement( 'input' ); this .guzik.onclick = function () { this .value = ?????? } document.getElementsByTagName( 'body' )[0].appendChild( this .guzik); } this .init(); } var s = new _KlasaObiektu(); |
Po wywołaniu metody init tworzymy nowy guzik. Po jego kliknięciu powinien on przyjąć value z _KlasyObiektu. Jak jednak to zrobić, skoro instrukcja this wewnątrz obiektu guzika wskazuje na niego samego?
Jest na to prosty sposób. Wystarczy utworzyć zmienną, wskazującą na dany obiekt, a potem wykorzystać ją przy odwoływaniu z obiektów podrzędnych:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
_KlasaObiektu = function () { this .o = this ; this .imie = 'Marcin' ; this .wzrost = 183 this .guzik = null ; this .init = function () { var ob = this .o; ob.guzik = document.createElement( 'input' ); ob.guzik.onclick = function () { this .value = ob.wzrost } document.getElementsByTagName( 'body' )[0].appendChild(ob.guzik); } this .init(); } var s = new _KlasaObiektu(); |
Jesto to bardzo ważna technika – do zapamiętania albo do wytatuowania na czole. Będziemy często ją stosowali pisząc obiektowo w Javascripcie.