2013-04-23 11 views
8

mam ten kod:Przypisywanie prototyp wewnątrz konstruktora

var MyClass = function(b) { 
    this.a = b; 
    this.getA = function() { 
     return that.a; 
    } 
} 

var SecondClass = function(b) { 
    this.prototype = new MyClass(b); 
    this.getB = function() { 
     return 6; 
    } 
} 

var a = new SecondClass(2); 
console.log(a.getA()); 

Wyjście mówi mi, że nie ma metody nazywanej Geta()

Sądziłem, że robi this.prototype = new MyClass() wewnątrz konstruktor dla SecondClass spowodowałby, że odziedziczyłby metody z MyClass?

Jestem pewien, że istnieją lepsze sposoby, aby to zrobić, ale staram się zrozumieć zachowanie prototypowego słowa kluczowego.

+1

"Prototype" nie jest słowem kluczowym. – Pointy

+1

'return that.a;' powinno być 'return this.a;' btw. –

Odpowiedz

11

prototype jest specjalną właściwością funkcji konstruktora, a nie na przykład.

Po wywołaniu funkcji konstruktora new Func(), silnik będzie utworzyć nowy obiekt, który dziedziczy Func.prototype a następnie ustawia this wewnątrz funkcji konstruktora, aby odnieść się do nowego obiektu.

Tak więc, oprócz zwykłej własności, spadkobierstwo miało miejsce już w momencie, gdy miało miejsce zlecenie.

Ponieważ nie przypisujesz żadnych metod do MyClass.prototype, tutaj nie musisz nic robić z dziedziczeniem prototypów. Wszystko co musisz zrobić, to zastosować MyClass do nowo utworzonej instancji przy użyciu .call[MDN]:

var SecondClass = function(b) { 
    MyClass.call(this, b); 
    this.getB = function() { 
     return 6; 
    } 
}; 

Jednak należy add all methods that are shared by instances to the prototype i pozwól każde wystąpienie SecondClass dziedziczyć po nim. W ten sposób kompletna konfiguracja może wyglądać następująco:

var MyClass = function(b) { 
    this.a = b; 
} 
MyClass.prototype.getA = function() { 
    return this.a; 
}; 

var SecondClass = function(b) { 
    // call parent constructor (like 'super()' in other languages) 
    MyClass.call(this, b); 
} 
// Setup inheritance - add 'MyClass.prototype' to the prototype chain 
SecondClass.prototype = Object.create(MyClass.prototype); 
SecondClass.prototype.getB = function() { 
    return 6; 
}; 

var a = new SecondClass(2); 
console.log(a.getA()); 

Wszystko to will become easier in ES6.

+1

Dzięki, to pomogło trochę lepiej. Aby wyjaśnić, zakładam, że MyClass.protoype będzie po prostu instancją obiektu. Kiedy przypisuję rzeczy do MyClass.prototyp to tylko przypisuje je do konkretnej instancji obiektu (czyli prototypu do MyClass), a nie samej klasy Object. Dzięki – user350325

+0

Tak, dokładnie ... –

3

Właściwość o nazwie "prototyp" jest interesująca tylko dla obiektów będących funkcjami. Przypisanie wartości do właściwości "prototype" w konstruktorze nie ma wpływu (w tym przypadku); liczy się własność "prototypowa" samej funkcji konstruktora.

SecondClass.prototype = new MyClass(); 

lub coś. Prototyp obiektu konstruktora jest dzielony między wszystkie konstruowane instancje, więc posiadanie prototypu różni się w zależności od parametru konstruktora również nie ma większego sensu.

Inną rzeczą, jaką można zrobić byłoby nazwać „MyClass” konstruktor od wewnątrz „secondClass”:

function SecondClass(b) { 
    MyClass.call(this, b); 
    this.getB = function() { 
    return 6; 
    }; 
} 

To miałoby skutek składania this który jest skonstruowany w zaproszeniu new SecondClass() być urządzone przez Konstruktor "MyClass". To naprawdę nie byłoby dziedziczenie, ale dostaniesz funkcję "getA".

Powiązane problemy