W JavaSripcie istnieje bazowa klasa Object, która stanowi prototyp wszystkich pozostałych obiektów JavaScript. Można jej użyć bezpośrednio do utworzenia obiektu.
obj = new Object();
obj.x = 1;
obj.y = 2; |
obj = new Object();
obj.x = 1;
obj.y = 2;
lub alternatywnie
obj = {};
obj.x = 1;
obj.y = 2; |
obj = {};
obj.x = 1;
obj.y = 2;
Nawiasy klamrowe stanowią semantyczny skrót podobnie jak użycie nawiasów kwadratowych (arr = []) może zastąpić arr = new Array(). Tablica czyli Array jest jednym z wielu wbudowanych w JavaScript obiektów podobnie jak Window, Document itd.
Aby utworzyć niestandardowy obiekt należy najpierw zdefinować prototyp Klasy, której instancją dany obiekt będzie. Najprościej utworzyć prototyp metodą konstruktora.
var Foo = function() {
this.x = 1;
this.y = 2;
this.sum = function() {
return this.x + this.y;
}
} |
var Foo = function() {
this.x = 1;
this.y = 2;
this.sum = function() {
return this.x + this.y;
}
}
W konstruktorze definiujemy właściwości i metody. Nową instancję tworzy się z użyciem operatora new.
obj = new Foo();
alert(obj.x);
alert(obj.sum()); |
obj = new Foo();
alert(obj.x);
alert(obj.sum());
Do właściwości lub metod można się odwołać za pośrednictwem utworzonego w ten sposób obiektu, ale można też pominąć operację przypisania do zmiennej i wywołać metodę w sposób niemożliwy np. w PHP.
Wywołując obj = new Foo(); powołuje się do życia instancje prototypu Foo. Można następnie wywołać metodę obj.sum();. Metodę sum można też wywołać z pominięciem przypisania obiektu do zmiennej new Foo().someMethod(); Tak czy inaczej zawsze w trzeba w pierwszej kolejności utworzyć obiekt.
Definiowanie klas metodą prototypu jest łatwe i intuicyjne, nie mniej w przypadku powoływania wielu obiektów danego prototypu zalecany jest sposób definiowania metod z użyciem prototype (nie mylić z frameworkiem prototype).
var Foo = function() {
this.x = 1;
this.y = 2;
};
Foo.prototype.sum = function() {
return this.x + this.y;
} |
var Foo = function() {
this.x = 1;
this.y = 2;
};
Foo.prototype.sum = function() {
return this.x + this.y;
}
Różnica polega na tym, że w pierwszym przypadku przy powoływaniu do życia nowej instancji za każdym razem metoda „sum” tworzona jest na nowo, a w drugim przypadku jest to cały czas jedna i ta sama metoda. Zyskuję się na zaoszczędzonej pamięci co przy bardzo rozbudowanych skryptach nabiera znaczenia.
Zdefiniowanie metody z pominięciem słowa „prototype”:
var Foo = function() { };
Foo.sum = function(x, y) {
return x+ y;
} |
var Foo = function() { };
Foo.sum = function(x, y) {
return x+ y;
}
… daje możliwość wywołania metody klasy bez tworzenia obiektu Foo.sum(2,4); – to taki jakby odpowiednik metod statycznych w PHP. Analogicznie do metod statycznych w PHP użycie „this” wewnątrz takiej funkcji mija się z celem, więc gdybyśmy przez przypadek zdefiniowali:
var Foo = function() {
this.x = 1;
this.y = 2;
};
Foo.sum = function() {
return this.x + this.y;
} |
var Foo = function() {
this.x = 1;
this.y = 2;
};
Foo.sum = function() {
return this.x + this.y;
}
to wywołanie Foo.sum(); zwróci „NaN” a z kolei new Foo().sum(); zakończy się błędem „TypeError on line 1: (new Foo).sum is not a function”.
W JS można też utworzyć obiekt ad hock
var Foo = {
x: 1,
y: 2,
sum: function () {
return this.x + this.y;
}
} |
var Foo = {
x: 1,
y: 2,
sum: function () {
return this.x + this.y;
}
}
W tym wypadku Foo nie jest prototypem tylko instancją prototypu Object dlatego oczywistym jest wywołanie Foo.sum(); z pominięciem operatora new.