Korzystanie z obiektów i metod w języku JavaScript:
Obiekty natywne
Język JavaScript dostarcza nam do kilka natywnych/wbudowanych klas, z których możemy korzystać podczas tworzenia skryptów. Poniżej lista najważniejszych z nich :
- Number – reprezentuje liczbę
- Boolean – pozwala na konwersję wartości „nie-boolowskich” na boolowskie
- String – umożliwia przechowywanie tekstu i manipulowanie nim
- Array – służy do przechowywania tablic, czyli zmiennych zawierających wiele wartości
- Date – używane jest do pracy z datami
- Math – dostarcza funkcji matematycznych realizujących różnego rodzaju obliczenia
- RegExp – umożliwia tworzenie wyrażeń regularnych
Obiekty takie, są często tworzone w domyśle, tzn. jeśli przypisujemy do jakiejś zmiennej tekst, wówczas tak na prawdę, do zmiennej przypisywany jest obiekt ‚String’, jeśli liczbę to przypisywany jest obiekt ‚Number’ itd. Ponadto każdy z tych obiektów posiada szereg funkcji pozwalających na pracę z danymi, które reprezentują. Poniżej kilka przykładów:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
varnumber = 10; // w tle new Number(10)varstr = 'witaj swiecie'; // w tle new String('...')varbool = newBoolean(0); // poczatkowa wartość 'false'vararr = newArray('jeden', 'dwa', 'trzy'); // tablicavard = newDate(); // data ustawiona na terazvarregex = newRegExp('witaj', 'g'); alert(str.length); // pobieranie dlugosci tekstualert(str.toUpperCase()) // konwersja na wielkie litery alert(arr.length); // wielkosc tablicyalert(arr.indexOf('dwa')); // znajdowanie indeksu elementu d.setDate(d.getDate() + 1); // ustawianie datyalert(d.getDate()); // pobieranie daty alert(Math.PI); // wartosc liczby PIalert(Math.round(1.14567)); // zaokraglanie alert(str.match(regex)); // uzycie wyrazenia regularnego |
Powyższy przykład można sobie przetestować na jsfiddle.net.
To oczywiście tylko mały wycinek dostępnych w tych obiektach funkcji – myślę, że każdy jest w stanie zapoznać się z resztą sam, w miarę potrzeb i nie ma powodu, rozpisywać się na ten temat w tym poście.
Tworzenie własnych obiektów
Podobnie jak w innych językach programowania, wszystkie obiekty, zarówno natywne jak i własne, dziedziczą z obiektu ‚Object’. Samo tworzenie obiektów odbywa się również w sposób powszechnie znany, czyli poprzez użycie słowa kluczowego ‚new’.
W JavaScript nie ma jednak definicji klasy jako takiej. Zamiast tego, można napisać funkcję, którą później wywoła się jak konstruktor, właśnie za pomocą ‚new’ (pisałem już o tym w poprzednim poście). Dla porządku, poniżej przykład:
|
1
2
3
4
5
6
7
|
functionSomeConstructor(initialValue) { this.someValue = initialValue;}varsomeObject = newSomeConstructor('test'); alert(someObject.someValue); |
Jak widać, na początku mamy definicję funkcji ‚someConstrutor’, którą w linii piątej wykorzystujemy jako konstruktor tworzący obiekt ‚someObject’.
W tym miejscu możemy przejść od razu do tematu definiowania właściwości obiektów w JavaScript. W przykładzie widać, że w omawianej funkcji mamy przypisanie wartości ‚initialValue’ do zmiennej ‚someValue’ – w tym momencie (pamiętając, że ‚this’ odnosi się do klasy, która wywołuje daną funkcję), w „locie” tworzona jest właściwość, która później dostępna jest w kontekście danego obiektu (patrz linia siódma w przykładzie). Poniżej jeszcze jeden przykład:
|
1
2
3
4
|
varsomeObject = newObject();someObject.someValue = 'test'; alert(someObject.someValue); |
Kod powyższy pokazuje, że właściwości można tworzyć również po utworzeniu obiektu (linia druga).
Znamy już sposób tworzenia właściwości, czas więc teraz na definicję metody obiektu. Robi się to w sposób analogiczny, z tą różnicą, że zamiast do nowo tworzonej zmiennej obiektu przypisuje się funkcję, a nie konkretną wartość:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
functionsomeMethod(someValue) { alert(someValue);} varsomeObject = newObject();someObject.methodOne = function() { alert('witam z metody pierwszej!');}someObject.methodTwo = someMethod; // wywolaniasomeObject.methodOne();someObject.methodTwo('witam z metody drugiej!'); |
W powyższym przykładzie pokazane są dwa sposoby zdefiniowania metody obiektu. Sposób pierwszy – funkcja ‚inline’ (linie od szóstej do ósmej). Sposób drugi – standardowe zdefiniowanie funkcji (linie od pierwszej do trzeciej), a następnie przypisanie jej nazwy do odpowiedniej właściwości obiektu.
Wzorzec modułu
Jak słusznie zauważył w komentarzu do tego posta czytelnik Arek Bal, przy tworzeniu obiektów warto wspomnieć w tym miejscu o wzrorcu modułu.
Dotychczas dowiedzieliśmy się, że do tworzenia obiektów w JavaScript stosuje się funkcje pełniące jednocześnie rolę konstruktorów. Możliwe jest także definiowanie publicznych właściwości i metod już po utworzeniu obiektu (a także wielokrotne ich nadpisywanie). Są jednak sposoby na uzyskanie większej enkapsupalcji czyli odseparowanie właściwości i metod i uczynienie ich prywatnymi. I tutaj właśnie przychodzi nam z pomocą wzorzec modułu. Popatrzmy na taki przykład:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
varModule = function(initialValue) { // prywatna zmienna varsomeValue = initialValue; // prywatna metoda varcalculateValue = function() { returnsomeValue * 2; } return{ // publiczna metoda getValue : function() { // uzycie prywatnej metody (nie uzywamy 'this') returncalculateValue() - 1; } } } varobj = newModule(10);alert(obj.getValue());alert(obj.someValue); // zwraca wartosc 'undefined'alert(obj.calculateValue()); // blad |
Przypadek powyższy pokazuje, w jaki sposób za pomocą wzorca modułu można zrealizować enkapsulację zmiennych i metod. W powyższym kodzie, tworzymy zmienną ‚Module’ do której przypisujemy funkcję anonimową – posłuży ona nam później jako konstruktor obiektu. Do zaimplementowania zmiennej i metody prywatnej użyte zostało słowo kluczowe ‚var’ – jak dowiedzieliśmy się we wpisie na temat zakresu zmiennych w JavaScript, tak utworzone zmienne mają zasięg tylko wewnątrz tej funkcji, nie będą więc widoczne z zewnątrz. Nasza funkcja zwraca za to obiekt anonimowy, zawierający właściwość ‚getValue’, do której przypisana zostaje funkcja anonimowa – w ten sposób implementujemy metodę publiczną (tak samo implementuje się też właściwości publiczne).
Prototypy
Dwa akapity wcześniej, wspomniałem o tworzeniu właściwości i metod – dowiedzieliśmy się, że aby je stworzyć, wystarczy dokonać operacji przypisania wartości, a właściwość lub metoda utworzy się w locie. Istnieje jednak jeszcze jedna możliwość…
Każdy obiekt w JavaScript, posiada zdefiniowaną specjalną właściwość zwaną ‚prototype’. Dzięki niej mamy możliwość definiowania prototypów klasy, tzn. możemy zadeklarować zestaw właściwości i metod, które będzie posiadał każdy obiekt (utworzony za pomocą słowa kluczowego „new”). Zobaczmy więc przykład:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
functionTestClass(value) { this.someValue = value;} // jak wiemy funkcja jest równiez obiektem// wiec posiada także swój prototyp, a wiec:testClass.prototype.anotherValue = 'wartosc';testClass.prototype.method = function() { alert('funkcja method');} // tworzymy obiektvarobj = newTestClass('test'); // wywolania - wlasciwosc i metoda juz zdefiniowanealert(obj.anotherValue);obj.method(); |
Najpierw oczywiście funkcja będąca też jednocześnie konstruktorem. Następnie sedno sprawy – za pomocą właściwości ‚prototype’ definiujemy właściwość i metodę. Na koniec możemy zaobserwować, że właściwość i metoda są dostępne od razu po utworzeniu obiektu.
Na temat prototypów planowałem już od dłuższego czasu napisać osobnego posta. Myślę więc, że w kontekście egzaminu 70-480, to co napisałem na temat prototypów jest wystarczające, a do tematu jeszcze wrócę w przyszłości.
Znając już zagadnienie prototypów możemy przejść do najważniejszego i jednocześnie ostatniego paragrafu tego wpisu…
Dziedziczenie
Jako że język JavaScript jest w pełni obiektowy, możemy również w pełni korzystać z jego dobrodziejstw, czyli właśnie możliwości dziedziczenia. Niestety realizacja tego zagadnienia jest trochę inna niż w językach takich jak C#. Musimy zaimplementować je sami, przy użyciu właśnie właściwości ‚prototype’.
Spójrzmy najpierw na klasę rodzica:
|
1
2
3
4
5
6
7
8
9
10
11
|
functionParent() { // nic nie rób} // metody klasy rodzicaParent.prototype.getValue = function() { alert('metoda rodzica!!');}Parent.prototype.getAnotherValue = function() { alert('inna metoda rodzica!!');} |
Widzimy, że ma ona dwie metody. W kolejnym przykładzie stworzymy klasę dziedziczącą, która przesłoni pierwszą z nich:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
functionChild() { // nic nie rób} // dziedziczymy klase parent czyli// kopiujemy jej prototyp do prototypu dziecka!Child.prototype = newParent(); // przeslaniamy metodeChild.prototype.getValue = function() { alert('wywołano mnie z dziecka!');} varobj = newChild();obj.getValue();obj.getAnotherValue(); |
Sprawa wygląda więc całkiem prosto – dziedziczenie polega na przypisaniu do właściwości ‚prototype’ klasy dziedziczącej obiektu klasy rodzica. W ten sposób, wszystkie prototypowe właściwości i metody rodzica, widoczne są również w klasie dziecku. Dziedziczenie takie nazywamy „dziedziczeniem prototypowym”.
źródło strony :http://burczu-programator.pl/blog/obiekty-i-metody-w-jezyku-javascript ; http://burczu-programator.pl/blog/javascript-wszystko-o-konstruowaniu-obiektow
Łukasz Piwowarski