7

czytałem na javascript ogród http://bonsaiden.github.com/JavaScript-Garden/ o prototypu w JavaScript i jednego z jego przykład idzie tak:dlaczego wymieniając rzeczywisty konstruktor klasy w javascript ważne

function Foo() { 
    this.value = 42; 
} 
Foo.prototype = { 
    method: function() {} 
}; 

function Bar() {} 

// Set Bar's prototype to a new instance of Foo 
Bar.prototype = new Foo(); 
Bar.prototype.foo = 'Hello World'; 

// Make sure to list Bar as the actual constructor <------------------- 
Bar.prototype.constructor = Bar; 

Wskazówka linia, która czyta Upewnij się, list Bar jako rzeczywisty konstruktor. Naprawdę jestem zagubiony w tym, co to robi. Próbowałem tworzenia nowych instancji Bar() z i bez ostatniego wiersza. Ale wywołanie "value" lub "method" dla tych instancji zwraca dokładnie to samo. Zastanawiam się więc, jaka jest potrzeba (zakładam, że musi być) określenie konstruktora?

Dziękujemy!

Odpowiedz

6

Każda funkcja ma właściwość prototype, to przypisana funkcja, gdy obiekt jest tworzony, wskazuje nowo utworzonego obiektu, która dziedziczy z Object.prototype, a to ma właściwość constructor, że po prostu wskazuje powrót do samej funkcji.

Celem właściwości prototype jest przedstawienie sposobu implementacji dziedziczenia przy użyciu funkcji konstruktora. Kiedy wywołujesz funkcję z operatorem new, utworzy on nowy obiekt, który dziedziczy po tym konstruktorze: prototype.

Teraz celem własności constructor jest mieć sposób, aby odnieść się do konstruktora, który stworzył przedmiot, na przykład:

function Foo() {} 
// default value of the property: 
Foo.prototype.constructor == Foo; // true 

Ta właściwość jest dziedziczona przez „wystąpienia” Foo , dzięki czemu można wiedzieć, które konstruktor został użyty do utworzenia obiektu:

var foo = new Foo(); 
foo.constructor == Foo; 

Jeśli przypiszesz nowy obiekt do prototypu funkcja, ten związek jest stracone:

function Bar() {} 
Bar.prototype = { inherited: 1 }; 

Bar.prototype.constructor == Bar; // false 
Bar.prototype.constructor == Object; // true 

i wpływa także wystąpień funkcję:

var bar = new Bar(); 
bar.constructor == Bar; // false 
bar.constructor == Object; // true 

Inny podobny przypadek jest wtedy, gdy dwa lub więcej poziomów dziedziczenia za pomocą konstruktorów, najczęstszym sposobem jest używany do określenia relacji dziedziczenia między funkcjami, należy przypisać właściwość prototype drugiego poziomu, np.:

function Parent() {} 

function Child() {} 
Child.prototype = new Parent(); 

Powyższy kod ma kilka problemów, po pierwsze, to realizuje logikę konstruktora dominującej do tworzenia relacji dziedziczenia, ale to już inna historia, w powyższym przykładzie właściwość constructor ma również wpływ, ponieważ możemy zastąpić całkowicie przedmiotem Child.prototype:

var child = new Child(); 
child.constructor == Parent; // true 

Jeśli zastąpić zastąpić wartość majątku Child.prototypeconstructor po przypisaniu go, to pokaże oczekiwane zachowanie:

function Child() {} 
Child.prototype = new Parent(); 
Child.prototype.constructor = Child; 

var child = new Child(); 
child.constructor == Child; // true 
+0

Dzięki za tak szczegółowe wyjaśnienie. To wszystko ma sens. Jedyne, co ciągle mnie trapi, ale mogę przeoczyć to, że wygląda trochę okrężnie w Child.prototype.constructor = Child –

+1

@Nik, Nie ma za co! Tak, rzeczywiście jest okrągły z założenia, np .: 'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;' ;-) – CMS

2

Uważam, że ma to związek z tworzeniem paska z nowym słowem kluczowym. Wierzę, że przy użyciu nowych będzie szukać Bar.prototype.constructor. Przed tą linią obiekt powiązany z Bar.prototype.contructor jest typu Foo, więc gdy zostanie utworzony bez tej linii, stworzy obiekt Foo zamiast obiektu Bar.

+0

Dzięki Keith! ; To jest zwięzłe i na temat wyjaśnienia, jak również –

+1

Nie ma za co! Jeśli to pomogło, możesz dać +1? –

Powiązane problemy