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
|
var number = 10; // w tle new Number(10) var str = 'witaj swiecie' ; // w tle new String('...') var bool = new Boolean(0); // poczatkowa wartość 'false' var arr = new Array( 'jeden' , 'dwa' , 'trzy' ); // tablica var d = new Date(); // data ustawiona na teraz var regex = new RegExp( 'witaj' , 'g' ); alert(str.length); // pobieranie dlugosci tekstu alert(str.toUpperCase()) // konwersja na wielkie litery alert(arr.length); // wielkosc tablicy alert(arr.indexOf( 'dwa' )); // znajdowanie indeksu elementu d.setDate(d.getDate() + 1); // ustawianie daty alert(d.getDate()); // pobieranie daty alert(Math.PI); // wartosc liczby PI alert(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
|
function SomeConstructor(initialValue) { this .someValue = initialValue; } var someObject = new SomeConstructor( '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
|
var someObject = new Object(); 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
|
function someMethod(someValue) { alert(someValue); } var someObject = new Object(); someObject.methodOne = function () { alert( 'witam z metody pierwszej!' ); } someObject.methodTwo = someMethod; // wywolania someObject.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
|
var Module = function (initialValue) { // prywatna zmienna var someValue = initialValue; // prywatna metoda var calculateValue = function () { return someValue * 2; } return { // publiczna metoda getValue : function () { // uzycie prywatnej metody (nie uzywamy 'this') return calculateValue() - 1; } } } var obj = new Module(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
|
function TestClass(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 obiekt var obj = new TestClass( 'test' ); // wywolania - wlasciwosc i metoda juz zdefiniowane alert(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
|
function Parent() { // nic nie rób } // metody klasy rodzica Parent.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
|
function Child() { // nic nie rób } // dziedziczymy klase parent czyli // kopiujemy jej prototyp do prototypu dziecka! Child.prototype = new Parent(); // przeslaniamy metode Child.prototype.getValue = function () { alert( 'wywołano mnie z dziecka!' ); } var obj = new Child(); 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