2016-04-02 21 views
2

Um meinen JavaScript-Code zu strukturieren, möchte ich classes, den syntaktischen Zucker für die Prototyp-Vererbung, neu zu ES6 verwenden. Ich habe jedoch Probleme: Es scheint, dass meine Prototyp-Methoden nicht wie erwartet funktionieren, wodurch ich das Gefühl habe, dass ich ein fundamentales Missverständnis von JavaScript-Klassen habe und/oder wie sie funktionieren.Warum funktionieren meine Klassenprototypen nicht?

Nehmen Sie den folgenden Code, der einen traditionellen Konstruktor Cat deklariert und seinen Prototyp modifiziert, und eine ES6-Klasse Dog mit einer darin definierten Prototyp-Methode.

// Traditional Cat Constructor 
// =========================== 
function Cat(name) { 
    this.name = name; 
    this.sound = "Meow."; 
} 

Cat.prototype.speak = function() { 
    console.log(this.sound || "I don't make a sound."); 
}; 


// Dog via ES6 Class 
// ================= 
class Dog { 
    constructor(name) { 
     this.name = name; 
     this.sound = "Woof!"; 
    } 

    speak() { 
     console.log(this.sound); 
    } 
} 

var cat = new Cat("Bella"); 
var dog = new Dog("Sparky"); 

In NodeJS (mit 4.4.2 und 6.0.0 vorge getestet), wenn ich versuche, den Prototyp einer Instanz von Dog zu bekommen, ich ein leeres Objekt, aber ich bin Immer noch in der Lage, die Prototyp-Methode für die Instanz aufzurufen.

Object.getPrototypeOf(cat); 
// -> Cat { speak: [Function] } 

Object.getPrototypeOf(dog); 
// -> Dog {} 

cat.speak(); 
// -> Meow. 

dog.speak(); 
// -> Woof! 

In Google Chrome, wo ich das Ergebnis erwarten die gleiche sein (da Knoten seine Engine verwendet), erhalte ich stattdessen das erwartete Ergebnis:

Object.getPrototypeOf(cat); 
// -> Object {} 
// ->  constructor: function Cat(name) 
// ->  speak: function() 
// ->  __proto__: Object 

Object.getPrototypeOf(dog); 
// -> Object {} 
// ->  constructor: function(name) 
// ->  speak: function() 
// ->  __proto__: Object 

Ich habe einen Fehler in Node bekommen, der besagt, dass die Prototyp-Methoden, die ich in einer Klasse definiert habe, keine Funktionen von Instanzen ihrer Klassen waren, was der einzige Grund ist, warum ich das bemerkt habe, aber leider jetzt Das kann ich nicht reproduzieren.

Unabhängig davon, das oben genannte scheint nicht richtig, gibt es eine Erklärung dafür, warum dieser Code auf diese Weise verhält?

+0

siehe auch [Funktionen (Methoden) einer Klasse abrufen] (http://stackoverflow.com/q/31054910/1048572) – Bergi

Antwort

7

Warum funktionieren meine Klassenprototypen nicht?

Nur weil die Ausgabe nicht wie erwartet ist, bedeutet es nicht, dass es nicht funktioniert. Weder der Knoten REPL noch console sind standardisiert. Implementierungen sind völlig frei, um auszugeben, was immer sie wollen.

Die einzige Möglichkeit, wirklich zu wissen, ob etwas "funktioniert" oder nicht, ist es zu benutzen. Versuchen Sie also, dog.speak() anzurufen.

Unabhängig davon, das oben genannte scheint nicht richtig, gibt es eine Erklärung dafür, warum dieser Code auf diese Weise verhält?

Klassenmethoden sind nicht-zählbare Eigenschaften, daher zeigen sie nicht in dem Knoten ausgegeben. Vereinfachtes Beispiel:

> var foo = {}; 
undefined 
> Object.defineProperty(foo, 'bar', {value: 42, enumerable: false}); 
{} 
> console.log(foo); 
{} 
undefined 
> foo.bar 
42 
> 

In Bezug auf die Chrome-Ausgabe scheint es, dass Sie das Objekt erweitert haben. Chrome zeigt immer aufzählbare und nicht aufzählbare Eigenschaften.

> var foo = {}; 
    undefined 
> Object.defineProperty(foo, 'bar', {value: 42, enumerable: false}); 
    Object {bar: 42} 
> console.dir(foo); 
    Object 
    bar: 42 
    __proto__: Object 
    undefined 

Es scheint auch, dass das Chrome auch nicht aufzählbare Eigenschaften im Sommer zeigt. Auch wenn Chrome und Node dieselbe Engine verwenden, teilen sie wahrscheinlich nicht die gleiche Logik für console oder die Ausgabegenerierung.

Verwandte Themen