2016-11-11 1 views
4

Ich bin so eine Person, die alles in der Tiefe wissen muss ... Also, ich habe viele unterrichtete Fächer durchlaufen und ich habe meinen Fuß in die Tiefen der Prototyp-Vererbung gesteckt.
Ich habe eine klare Vorstellung davon, wie es in ES5 funktioniert (Jede Funktion hat diese spezielle Prototypeigenschaft, die auf ein Objekt zeigt, auf dem sie basiert. Dieses Objekt hat eine .constructor-Eigenschaft, die auf die Funktion usw. verweist). .Wie viel ES6-Klassen unterscheiden sich von ES5-Stil?

So, jetzt lassen Sie uns ES5 Beispiel sehen:

function Bunny(name) { 
    this.name = name 
} 

Bunny.prototype.sayName = function() { 
    console.log('Im',this.name) 
} 

Diese ist ziemlich klar: Funktion Hase bekommt Argument name, die auf ein neues Objekt zuweisen geht werden.

Die nächste Zeile fügt dem Prototyp der Funktion eine Funktion hinzu, die den aktuellen Namen zurückgibt.

Lassen Sie uns ES6-Klasse jetzt:

class Fox{ 
    constructor(name){ 
     this.name = name; 
    } 

    sayName() { 
     console.log('Im', this.name) 
    } 
} 

gleiche Material hier: Constructor hier ist wie unsere Häschen-Funktion. Aber sayName in Fuchs ist nicht das gleiche wie sayName in Bunny.
Lassen Sie uns die Instanzen erstellen:

let bunny = new Bunny('Henry'); 
let fox = new Fox('Jerry'); 

Und nun, ihre Prototypen überprüfen:

console.log(Object.getPrototypeOf(bunny)) 
console.log(Object.getPrototypeOf(fox)) 

Was bekommen wir?

//using repl.it - ES6 
{ sayName: [Function] } 
{} 

Warum ist das?

Ich dachte, es könnte sein, weil wir Funktion sayName auf Bunnys Prototyp direkt setzen. Also habe ich es so weit geändert:

function Bunny(name) { 
    this.name = name 

    //Warning - Bad practice ahead! 
    this.sayName = function() { 
     console.log('Im',this.name) 
    } 
} 

Ergebnis:

//using repl.it - ES6 
{} 
{} 

diesem Sinn haben würde, wenn nicht dies:

console.log(bunny.hasOwnProperty('sayName')) 
console.log(fox.hasOwnProperty('sayName')) 

Was bedeutet, fox nicht sayName nicht besitzt auf er, entweder Prototyp zeigt es hat es. Fehle ich hier etwas? Warum sind sie anders?

+0

Warum ist das zweite Beispiel eine schlechte Übung? – evolutionxbox

+0

@evolutionxbox Weil es für jede Instanz eine neue Funktion erstellt. –

+0

Verwenden Sie niemals 'console.log', um ein Objekt zu untersuchen. Verwenden Sie 'console.dir'. –

Antwort

7

In ES6-Klassen sind alle Methoden nicht aufzählbar. Wenn Sie also einen Prototyp einer Instanz einer ES6-Klasse protokollieren, erhalten Sie etwas, das wie ein leeres Objekt aussieht.

Sehen Sie folgendes Beispiel:

const obj = new (class {method() {}}); 
 

 
console.log(Object.getPrototypeOf(obj)); // {} 
 
console.log(typeof Object.getPrototypeOf(obj).method); // function

In ES5 definieren Sie eine Methode, indem es einer Eigenschaft der Klasse Prototyp zuweisen, die es enumerable macht.Wenn Sie die gleiche Wirkung wie mit ES6 Klassen erreichen wollten, könnten Sie Object.defineProperty() statt:

const TestClass = function TestClass() {}; 
 
Object.defineProperty(TestClass.prototype, 'method', { 
 
    value: function() {}, 
 
    writable: true, 
 
    enumerable: false, 
 
    configurable: true, 
 
}); 
 
const obj = new TestClass(); 
 

 
console.log(Object.getPrototypeOf(obj)); // {} 
 
console.log(typeof Object.getPrototypeOf(obj).method); // function


Und fox.hasOwnProperty('sayName') kehrt false weil hasOwnProperty() prüft nur für eigene Eigenschaften und sayName ist in der Prototypkette. Wenn Sie auch nach Eigenschaften in der Prototypkette suchen möchten, können Sie den Operator in verwenden: 'sayName' in fox gibt true zurück.


Siehe auch Enumerability and ownership of properties auf MDN.

+0

Ah, das habe ich verpasst! Schön! Auch ging ich voran und füge meinen Code in babel transpiler -> hat den Code in ES5. Es gibt eine for-Schleife, die alle Eigenschaften im Konstruktor durchläuft und prüft, ob sie aufzählbar sind -> 'Methoden' sind nicht! Wenn sie mit '.propertyIsEnumerable' überprüft werden, wird false ausgegeben. Außerdem habe ich '.hasOwnProperty' auf' fox' und 'fox.prototype' mit dem gleichen Ergebnis überprüft. Aber ich habe es in meiner Frage nicht erwähnt, mein Schlechter. – Krizzu

Verwandte Themen