2016-05-03 16 views
1

Warum funktioniert der folgende Code nur unter Node.js 5.x und 6.x, aber bricht in 4.x und früheren Versionen?Versionsabhängige Vererbung in Node.js

Gibt es eine Möglichkeit, es so zu ändern, dass es in jedem Node.js 0.10.x - 6.x funktioniert?

'use strict'; 

var util = require('util'); 

function Parent() { 
} 

Parent.prototype.show = function() { 
    return this.msg(); // virtual-like call; 
}; 

function Child() { 
} 

Child.prototype.msg = function() { 
    return 'Hello!'; 
}; 

util.inherits(Child, Parent); 

var test = new Child(); 

console.log(test.show()); 

In Node.js 5.x und 6.x zeigt es Hello!. Und in jeder früheren Version von Node.js wird TypeError: this.msg is not a function angezeigt.

Antwort

1

Betrachtet man die zwei verschiedenen Versionen von Code, fand ich, dass der einzige Unterschied zwischen ihnen die Art und Weise ist, in der prototypische Vererbung erreicht wird.

4.x

 
ctor.prototype = Object.create(superCtor.prototype, { 
    constructor: { 
     value: ctor, 
     enumerable: false, 
     writable: true, 
     configurable: true 
    } 
}); 

Wo ctor der Kindkonstruktors und superCtor ist die Mutter Konstruktor.

Master

 

Object.setPrototypeOf(ctor.prototype, superCtor.prototype); 

Wo ctor der Kindkonstruktors und superCtor ist die Mutter Konstruktor.


Für die Versionen 4.x (und unten wahrscheinlich), wird die Eltern-Prototyp zum Prototyp des Kindes übertragen, damit es ersetzt vollständig.

jedoch die neueste Version verwendet Object.setPrototypeOf welche Ich gehe davon aus nicht der Prototyp des Kindes ersetzen, sondern schont sowohl den Prototyp des Kindes sowie der Eltern Prototyp.

Update: Ich this in dem ECMAScript 2017 spec gefunden, wenn es keine Hilfe ist ...

+0

Leider existiert 'setPrototypeOf' nicht in Node.js 0.10.x. Irgendeine Idee, wie man das umgeht? –

+0

Sie können die [Polyfill] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf#Polyfill) für "Object.setPrototypeOf" verwenden oder Ihre eigenen benutzerdefinierten "Vererben" 'Funktion. –

+0

Die Verwendung des Polyfill für 'setPrototypeOf' ist die beste Lösung. Vielen Dank! –

3

Vor 5.0 zum Knoten verwendet util.inheritsObject.create() die Vererbungskette zu schaffen. Dies hatte leider einen Fehler. Alles, was Sie an Child.prototypevorher an die Verwendung von util.inherits angefügt haben, wurde entfernt - was Ihren Fehler verursacht. Ab 5.0 und höher verwendet der Knoten unter der Haube.

Zum Glück ist die Lösung super einfach. Verschieben Sie den Anruf , bevor Sie Methoden zu Child.prototype hinzufügen.

Der folgende Code funktioniert von 0.10 bis 6.0.

'use strict'; 

var util = require('util'); 

function Parent() { 
} 

Parent.prototype.show = function() { 
    return this.msg(); // virtual-like call; 
}; 

function Child() { 
} 

util.inherits(Child, Parent); 

Child.prototype.msg = function() { 
    return 'Hello!'; 
}; 

var test = new Child(); 

console.log(test.show()); 
+0

Große Antwort, auf den Punkt! Dieser kleine Trick hat es geschafft! :) –

+0

Nach dem Versuch, es zu verwenden, fand ich es nicht über mehrere Module verwendbar. Es kann nur innerhalb einer JavaScript-Datei funktionieren, die kaum verwendbar ist.Ich fand es, dass die Verwendung des Polyfill für 'setPrototypOf' (frühere Antwort von @Blaze) eine viel bessere Lösung ist. –

+0

Können Sie mir ein Beispiel geben, wo es nicht verwendbar ist? –