2015-07-03 8 views
5

Ich glaube, ich verstehe prototypische Vererbung in JS aber habe Probleme beim Schreiben von Code, um eine bestimmte Idee zu demonstrieren, die ich habe. Betrachten Sie dieses extrem einfaches Szenario, in dem Manager-Objekte aus Mitarbeitern Objekten ableiten:Prototypische Vererbung ohne Prototyp?

function Employee() 
{ 
    this.name = "Axel"; 
    this.dept = "R&D"; 
} 

function Manager() 
{ 
    Employee.call(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Die Ausgabe lautet:

Manager {name: "Axel", dept: "R&D", reports: Array[3]} 

Seltsamerweise scheint es mir, dass wir demonstrieren prototypische Vererbung gelungen. Aber die Fakten, die wir nicht verwendeten prototype überall stört mich. Sicherlich ist der obige Code nicht der richtige Weg?

Kann jemand ein Beispiel geben, das zeigt, dass der obige Ansatz fehlschlägt?

(By the way, kommt das Beispiel von der offiziellen Mozilla docs, abzüglich die Einstellung von Prototypen: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model)

+0

Es ist nichts falsch mit dem obigen Ansatz. In diesem Fall modifizieren Sie nur ein * einzelnes Objekt *, während Sie mit dem Prototyp * alle Objekte * mit dem gleichen Prototyp modifizieren können. – meskobalazs

+0

@meskobalazs Ich fürchte, mein klassisch trainierter Geist folgt nicht. Wenn ich eine Menge 'neuer Manager()' schreibe, würde ich nicht alle drei Eigenschaften (Name, Abteilung und Berichte) erhalten? Daher scheint es, dass alle Objekte, die weiter unten liegen, modifiziert werden. – dotslash

+2

Sie verwenden hier keine Prototypen oder prototypische Vererbung. Stattdessen legen Sie Eigenschaften direkt für jedes einzelne Objekt fest. –

Antwort

2

Wir haben dies in verschiedenen Kommentaren versucht, aber ich wollte ein Beispiel geben, das zur Klärung beitragen könnte. Beginnend mit dem Original-Code:

function Employee() 
{ 
    this.name = "Axel"; 
    this.dept = "R&D"; 
} 

function Manager() 
{ 
    Employee.call(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Wir sehen auch so genau das gleiche tun könnte:

function setEmployee(emp) 
{ 
    emp.name = "Axel"; 
    emp.dept = "R&D"; 
} 

function Manager() 
{ 
    setEmployee(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Jetzt haben wir .call() oder .apply() oder so etwas Phantasie nicht verwendet. Der Konstruktor Manager ruft einfach eine andere Funktion auf und übergibt seinen Wert this direkt als Argument. Der Code macht genau so wie früher.

Wir könnten es einen Schritt weiter:

function setEmployee(emp) 
{ 
    emp.name = "Axel"; 
    emp.dept = "R&D"; 
} 

function createManager() 
{ 
    var emp = {}; 
    setEmployee(emp); 
    emp.reports = ["Report 1", "Report 2", "Report 3"]; 
    return emp; 
} 

console.log(createManager()); 

Jetzt sind wir nicht Konstrukteure verwenden, und nicht einmal this mit - wir sind nur ein Objekt explizit erstellen und um zwischen den Funktionen vorbei, und die Code macht immer noch das Gleiche!

+0

Danke für die Mühe. Ja, es macht die Dinge sehr klar. – dotslash

1
new Manager() instanceof Manager 
> true 
new Manager() instanceof Employee 
> false 
+0

Ausgezeichnet! Zumindest bestätigt es, dass ich Unsinn im Namen der Vererbung machte. : D – dotslash

2

Sie haben nicht wirklich etwas erben. Sie haben einfach eine Funktion auf ein bestimmtes Objekt angewendet. Ich denke, viele funktionale Sprachen können dies tun.

Vererbung wird verwendet, gut zu erben, nicht nur nicht verwandte Funktionen auf ein bestimmtes Objekt anwenden.

In Ihrem Beispiel behandeln Sie nicht, wie Methoden zum Beispiel erben. Selbst wenn Sie beispielsweise versucht haben, die Methodenvererbung über eine Proxy zu implementieren, bedeutet das nicht, dass Sie die Eltern geerbt haben.

+0

Ah! Also meinst du "Name" und "Abteilung" oben gehören zu "Manager" und nicht "Mitarbeiter"? Wenn ja, wie kann ich dies bestätigen? – dotslash

+1

In Ihrem Beispiel gehören "name" und "dept" weder zu "Manager" noch zu "Mitarbeiter". Sie sind Eigenschaften, die Sie auf jedes einzelne Objekt einstellen, und haben nichts mit den Prototypen von 'Manager' oder' Employee' zu ​​tun. –

+0

Anders gesagt, haben Sie ein Objekt mit eigenen Eigenschaften erstellt, die Sie explizit für das einzelne Objekt festgelegt haben. Es macht keinen Unterschied, ob diese Eigenschaften in der Funktion "Manager" oder der Funktion "Employee" oder in einer anderen zufälligen Funktion, die Sie explizit aufrufen, eingestellt sind. In jedem Fall sind sie einfach Eigenschaften des * individuellen Objekts *. –

Verwandte Themen