2012-01-31 8 views
21

I niedawno rozpoczął czytania na OOP javascript i jednej rzeczy, że autorzy zdają się przeskoczyć jest, gdy obiekt została uznana i nagle widzę „A.prototype.constructor = A; Na przykładDlaczego warto używać obiektu object.prototype.constructor w javascript OOP?

var A = function(){}; // This is the constructor of "A" 
A.prototype.constructor = A; 
A.prototype.value = 1; 
A.prototype.test = function() { alert(this.value); } 
var a = new A(); // create an instance of A 
alert(a.value); // => 1 

więc uruchomić komendę w Firebug "var a = function() {};". a następnie "A.Constructor" która ujawnia, że ​​jest to funkcja rozumiem
uruchomić kod „A.prototype.. constructor = A; "i pomyślałem, że to zmienia konstruktor A z Function na A.

Właściwość konstruktora A została zmieniona Ged, prawda? Zamiast tego, kiedy uruchamiam "A.constructor", daje mi on funkcję function().

O co ci chodzi?

Widzę także A.constructor.prototype.constructor.prototype .. co się dzieje?

+6

których autorzy, gdzie? –

+0

Kod, z którego go otrzymałem, to http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures – Matt

Odpowiedz

12

Jeżeli A dziedziczy B używając A.prototype = new B();, trzeba zresetować właściwość konstruktora dla klasy A, stosując A.prototype.constructor=A;, inaczej instancji miałby konstruktora B.

W twoim przypadku, A.prototype.constructor === A zwróci true, tak A.prototype.constructor = A nic nie zrobił.

+0

Interesujące, więc A.prototype.constructor = A; czy A wyizoluje się z B? W ten sposób można rozszerzyć więcej właściwości za pomocą A.prototype bez dodawania więcej właściwości do B? – Matt

+0

Nie ma nic na izolację, tylko upewnij się, że A ma właściwą właściwość konstruktora. – xdazz

+11

Jaki jest cel posiadania właściwej właściwości konstruktora? Kiedy A.prototype.constructor kiedykolwiek był rzeczywiście konsultowany w praktyce? To nie wpływa na zachowanie tworzenia nowych instancji A, afaików. Odpowiedź musi być tak oczywista, że ​​generalnie nie jest wyświetlana, dlatego mnie umyka :-) – Yetanotherjosh

4

Można szybko przetestować, że dodatkowy przydział robi absolutnie nic:

var A = function() {}; 
A.prototype.constructor === A; // true -- why assign then? 

Resetowanie właściwość konstruktora ma sens tylko jeśli już przydzielony nowy obiekt prototypowy do klasy, zastępując oryginalny konstruktor:

var A = function() {}; 
A.prototype = protoObject; // some object with members that you'd like to inherit 
A.prototype.constructor = A; // reset constructor 

W twoim przypadku autor może ślepo robić to jako dobrą praktykę, nawet w przypadkach, gdy nie jest to konieczne.

2

Ten kod jeśli często używają w JS klasyczny wzór dziedziczenia (kod jest od wzorców JavaScript Stoyan Stefanov):

function inherit(C, P) { 
    var F = function() {}; 
    F.prototype = P.prototype; 
    C.prototype = new F(); 
    C.uber = P.prototype; 
    C.prototype.constructor = C; 
} 

przypisać właściwą konstruktor do klasy dziecięcej.

W twoim przypadku nie zadziałało, od A.prototype.constructor === A przed zleceniem.

1

Może chcesz zobaczyć moją odpowiedź na podobne pytanie:

https://stackoverflow.com/a/19616652/207661

TL; DR: konstruktor nie jest własność z instancji. Aby wygląd rzeczy był spójny, interpreter języka JavaScript musi ustawić prototype.constructor, aby sam działał. Ta funkcja może być używana w funkcjach, które działają ogólnie na wiele różnych typów obiektów.

1

Według MDN, Wszystkie obiekty dziedziczą właściwość konstruktora od swojego pierwowzoru:

Example 1: 
var o = {}; 
o.constructor === Object; // true 

..

Example2: 
function Tree() { 
}  
var theTree = new Tree(); 
console.log(theTree.constructor === Tree); // true 

W czasie wykonywania nie ma różnicy w zależności od wartości właściwości constructor.

Jednak, ponieważ własność constructor zwraca odwołanie do funkcji Object, która utworzyła prototyp instancji, należy zresetować właściwość constructor, gdy przypiszą nowy prototyp do funkcji Object.

var Forest = function() {}; 
Forest.prototype = theTree; 
console.log(new Forest().constructor === Tree); // true 
Forest.prototype.constructor = Forest; 
console.log(new Forest().constructor === Forest); // true 

https://jsfiddle.net/j1ub9sap/

Szczegółowe informacje: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

+0

Witam, wskakuję na twój komentarz kilka miesięcy później, ponieważ nie rozumiem tego zdania: "Jednak jako własność constructor zwraca odniesienie do funkcji Object, która stworzyła prototyp instancji " Funkcja Object nie tworzy prototypu instancji, bezpośrednio tworzy instancję no? Co to dokładnie oznacza? Dzięki – jobou

+0

Oznacza to, że Jeśli las odziedziczy Drzewo używając Forest.prototype = new theTree(), instancje Lasu będą miały konstruktor TheTree. Aby mieć las jako konstruktor, należy zresetować właściwość konstruktora dla lasu, używając Forest.prototype.constructor = Forest. –

+0

Rozumiem twój przykład. Moje pytanie dotyczyło bardziej oficjalnej dokumentacji: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor. Mówi "Zwraca referencję do funkcji Object, która stworzyła instancję prototyp.". Jednak wszystkie przykłady na tej stronie nie mają przesłoniętego prototypu. Nie ma niestandardowego dziedziczenia: 'var a = []; a.constructor === Array; 'Dlaczego więc nie mówi, że" konstruktor jest odwołaniem do funkcji Object, która stworzyła samą instancję "? Dzięki – jobou

Powiązane problemy