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:

Kurs obiektowego JavaScript (17)

Zobacz również
Kurs obiektowego JavaScript (14)Łańcuch zasięgu i jego przerywanie. Gettery, settery.
Kurs obiektowego JavaScript (15)Wstęp do obiektów. Omówienie pól i metod. Konstruktory i słowo kluczowe new.
Kurs obiektowego JavaScript (17)Obiekt console i jego metody.
Kurs obiektowego JavaScript (18)Obiekty i konstruktory wbudowane.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.