2013-04-05 12 views
6

ich das Konzept der Vererbung in Javascript zu studieren und das Tutorial Ich betrachte verwendet diesen Code:Vererbung innerhalb Javascript

// define the Student class 
function Student() { 
    // Call the parent constructor 
    Person.call(this); 
} 

// inherit Person 
Student.prototype = new Person(); 

// correct the constructor pointer because it points to Person 
Student.prototype.constructor = Student; 

Meine Frage ist, warum ist es notwendig, sowohl den Konstruktor Eltern rufen , Person.call(this) und stellen Sie den Student Prototyp gleich ein neues Person Objekt (dh Student.prototype = new Person();)?

+0

http://stackoverflow.com/questions/892595/javascript-prototypal-inheritance?rq=1 –

Antwort

5

Es gibt zwei getrennte Fragen zu behandeln.

Die erste besteht darin, sicherzustellen, dass neue Student Objekte von Person Objekte erben. Deshalb tun Sie Student.prototype = new Person(). Das macht die Student.prototype ein Person so Student Objekte erben was auch immer das Objekt erbt (von Person.prototype).

Die zweite besteht darin, jedes Verhalten im Person-Konstruktor auf alle neuen Student Objekte anzuwenden. Deshalb tun Sie Person.call(this). Dies ist technisch nicht erforderlich, wenn der Person Konstruktor keinen Code hat, der das neue Objekt ändert, aber es ist immer noch eine gute Idee, es zu tun nur, wenn Sie einen Code zu Person später hinzufügen.


Randnotiz, wenn das Erbe der Einrichtung, ist es besser zu machen:

Student.prototype = Object.create(Person.prototype) 

... und Shim Object.create, wenn nötig. Auf diese Weise müssen Sie den Konstruktor Person nicht tatsächlich aufrufen, um ein neues Objekt zu erhalten, das von Person.prototype erbt. Auch dies ist manchmal kein Problem, aber manchmal gibt es im Konstruktor Nebenwirkungen, die beim Einrichten der Vererbung unerwünscht sind.

+0

Ich bin nur neugierig ..., was der Grund ist der Prototyp Konstruktor für die Einstellung? 'Student.prototype.constructor = Student;' – Polaris878

+2

+1 Für die Korrektur, die 'new Person()' löscht, was problematisch sein könnte, wenn der Elternkonstruktor über Parameter verfügt. Auch innerhalb des Konstruktors könnte man Argumente senden. –

+1

@ Polaris878: Es ist, weil der Standard 'Student.prototype' Objekt eine' .constructor' Eigenschaft hat, die die 'Student' Funktion verweist ... aber das Objekt ersetzt wird, so dass, wenn die' .constructor' Eigenschaft gewünscht wird, Es muss manuell zum neuen Objekt hinzugefügt werden. –

0

Nach ein paar Tests machen, um mein Verständnis, der Prototyp eines Objekts und die Eigenschaftsdeklarationen innerhalb seiner definierende Funktion sind gemacht getrennt. Wenn jedoch ein neues Objekt erstellt wird, zieht der Konstruktor Eigenschaften sowohl aus der definierenden Funktion als auch aus dem Prototyp des Objekts, das erstellt wird.

Zum Beispiel

function Person() 
{ 

    this.name = "james"; 
    this.age = "shfifty-five"; 


} 

console.log(Person.prototype.name); // prints "undefined", showing how declaring function Person() and Person.prototype are separate. 

Person.prototype.gender = "male"; 

var human = new Person(); 

console.log(human.name); // prints "james", showing how the object took properties from declaring function Person(). 
console.log(human.gender); // prints "male", showing how the object took properties from object prototype Person.prototype. 


function Student() 
{ 

    this.gpa = 4.00; 


} 



Student.prototype = new Person(); 

Student.prototype.constructor = Student; 


var myStudent = new Student(); 

console.log(myStudent.name); // prints "james" 
console.log(myStudent.gender); // prints "male" 
/*from above two lines, inheritance holds even though 1) Person() defining function was not called inside Student() defining function 
and 2) Person() defining function declares properties of Person object.*/ 
console.log(myStudent.gpa); // prints "4" 

Wie Sie sehen können, in diesem Fall die definierende Funktion Person die Eigenschaften ihres Objekts nicht verändert. Aber es ist noch nicht notwendig, die Person Funktion innerhalb der Konstruktor von Studenten zu nennen, weil die new Person() Konstruktor Eigenschaften ziehen wird von beiden Person.prototype und der function Person() Funktion definieren.

+1

Es kommt darauf an ... Jedes neue 'Student'-Objekt erbt Eigenschaften aus dem' Student.prototype'-Objekt. In Ihrem Beispiel, wenn Sie 'Student.prototype = new Person()' eingeben, werden einige Eigenschaften dem zugewiesenen Objekt 'Person' hinzugefügt, also werden diese natürlich vererbt. Was aber, wenn die Werte im Konstruktor "Person" nicht statisch sind? Wenn Sie bei den neuen 'Student'-Objekten nicht 'Person' aufrufen, verweisen sie immer auf dieselben Eigenschaftswerte, die für das Prototyp-Objekt festgelegt wurden. Wenn Sie möchten, dass statische Werte vererbt werden, sollten Sie sie auf "Person.prototype" setzen. –

Verwandte Themen