Kurs obiektowego JavaScript (16)
Autor: Damian Chodorek • Opublikowany: 2 października 2014 • Ostatnia aktualizacja: 8 lutego 2015 • Kategoria: javascript, kursy
Obiekt globalny. Pole constructor. Operator instanceof. Przekazywanie i porównywanie obiektów.
Na wstępie przypomnijmy sobie przykład z poprzedniej części.
function Pies(imie){
this.imie=imie;
this.powiedzImie=function(){
alert("Mam na imie "+this.imie);
};
}
var azor=Pies(); //brak new
Zabrakło słowa new
. Do czego więc odnosi się this
wewnątrz funkcji, skoro nie powstaje żaden nowy obiekt? Jak pamiętasz – do obiektu globalnego.
Co to jest? Jest to nadrzędny obiekt dostarczony przez środowisko hosta. Jego polami stają się wszystkie zmienne globalne. Jeśli przyjmiemy, że hostem jest przeglądarka, to obiekt ten będzie nazywał się window
.
var a=1; //tworzymy zmienną globalną
//oto 3 sposoby dostępu do zmiennej:
a; //sposób 1 - poprzez nazwę zmiennej bezpośrednio
window.a; // sposób 2 - jako pole obiektu window, z operatorem kropki
window['a']; //sposób 3 - podobnie, ale operator nawiasów
Co więc się dzieje naprawdę przy wywołaniu konstruktora bez new
?
function Pies(imie){ this.imie=imie; }
var azor=Pies("Azor"); //brak new
typeof azor; //"undefined"
imie; //"Azor"
/*powyższa zmienna została przypisana do obiektu globalnego window, a więc sama stała się zmienną globalną*/
Jeśli natomiast użyjesz new
, zostanie stworzony nowy obiekt i this
będzie odnosić się do niego.
var azor=new Pies("Azor");
typeof azor; //"object" - this odnosi się właśnie do tego obiektu, a NIE window
azor.imie; //"Azor"
imie; //BŁĄD! Nie ma takiej zmiennej globalnej
Wszystkie funkcje globalne, które do tej pory definiowaliśmy, również są metodami obiektu globalnego window
. Mało tego, wszystkie funkcje wbudowane, które poznałeś w części 10, również są metodami window
i można je wywołać jak poniżej.
window.parseInt("102"); //102
Pole constructor
Kiedy powstaje nowy obiekt, to niejawnie jest w nim tworzone pole constructor
. Zawiera ono referencję do funkcji, będącej konstruktorem obiektu.
azor.constructor; //"function Pies(imie){ this.imie=imie; }"
Skoro tak, to możemy tę referencję wykorzystać do stworzenia kolejnego obiektu i będzie to równoważne skorzystaniu ze zwykłego konstruktora.
var rex=new Pies("Rex");
rex=undefined;
//drugi sposób, równoważny pierwszemu:
rex=new azor.constructor("Rex");
No dobrze, a co w momencie gdy definiujemy obiekt przy użyciu {}
, a nie new
? Wówczas będzie posiadać wbudowany konstruktor Object()
, który zostanie omówiony w dalszej części.
var ob={};
ob.constructor; //function Object() { [native code] }
Operator instanceof
Powyższy operator pozwala sprawdzić czy obiekt, został utworzony przy pomocy danego konstruktora.
function Pies(){}
var ob1=new Pies(); //poprzez new
var ob2={}; //zwykła definicja
ob1 instanceof Pies; //true
ob2 instanceof Pies; //false
Konstruktor zwracający obiekt
Spójrz na poniższy kod.
function K(){ this.a; return {b: 2}; }
var k=new K();
typeof k.a; //undefined !!!
k.b; //2
k.constructor; //function Object() { [native code] }
Co się dzieje powyżej? Konstruktor K()
nie zwraca this
jako referencji do nowo utworzonego obiektu, zwraca za to inny obiekt, który został stworzony przy pomocy konstruktora Object()
. To możliwe tylko w przypadku gdy konstruktor zwraca obiekt. Jeśli zwracałby jakąkolwiek inną wartość, to wyszstko przebiegłoby normalnie i pod zmienną k
znalazłaby się wartość this
nowego obiektu.
Przekazywanie obiektów
W JS parametry przekazywane są poprzez referencję. To znaczy, że jeśli przekażesz obiekt do funkcji, w której go zmodyfikujesz, to modyfikacje będą widziane również po wyjściu z funkcji.
Porównywanie obiektów
Z tego faktu, że obiekty są trzymane pod referencjami, wynika iż operacja porównania obiektów zwróci true
tylko jeśli porównywane referencje wskazują na ten sam obiekt. Nie ważne, że obiekt pod drugą referencją będzie miał takie same wartości i nazwy pól. Będzie to inny obiekt i to się liczy.
var azor={ rasa: "terier" };
var rex={ rasa: "terier" };
rex===azor; //false
rex=azor; //teraz obie referencje będą wskazywać ten sam obiekt
rex===azor; //true
W tym artykule to wszystko. Przejdź do następnej części: