2017-02-14 2 views
0

Ich Prototyp Standalone-Klasse Vererbung: https://github.com/Jakobo/PTClassKlassenvererbung mit Klasse Prototyp-Schnittstelle

Und ich habe die folgenden Klassen:

App.hello = Class.create({ 

    initialize: function(args) { 
     this.name = args.name 
    }, 

    sayHello: function() { 
     console.log('Hello, ' + this.name); 
    }, 

    sayGoodbye: function() { 
     console.log('Goodbye, ' + this.name); 
    } 

}); 

App.yo = Class.create(App.hello, { 

    initialize: function($super) { 
     $super(); 
    }, 

    sayHello: function() { 
     console.log('Yo, ' + this.name); 
    } 

}); 

Wo die Idee ist, dass yo von hello erben und überschreiben ihre sayHello Methode. Aber auch in der Lage sein, die sayGoodbye Methode in seiner Elternklasse aufzurufen.

So nenne ich sie etwa so:

var test = new App.hello({name: 'Cameron'}); 
    test.sayHello(); 
    test.sayGoodbye(); 
var test2 = new App.yo({name: 'Cameron'}); 
    test2.sayHello(); 
    test2.sayGoodbye(); 

Allerdings erhalte ich die Fehlermeldung, dass Uncaught TypeError: Cannot read property 'name' of undefined für meine yo Klasse.

Wie erben ich ordnungsgemäß von meiner Klasse hello?

+1

Gerade dort löschte: PrototypeJS des 'CLASS' Sachen veraltet ist, und PrototypeJS ist nicht wirklich viel in diesen Tagen gehalten. Sie sollten besser die neue "Klassen" -Syntax lernen, die in ES2015 eingeführt wurde (aka "ES6") und, wenn nötig, für ältere Browser transpilieren. –

Antwort

1

Das Problem ist, dass yo ‚s initializer nicht auf die Argumente nicht übergeben Sie es an die übergeordnete Klasse übergeben:

initialize: function($super, args) { // *** 
    $super(args);     // *** 
}, 

Folglich wird der Code in hello‘ s initialize Funktion versucht, den name Eigenschaft lesen von args, aber args ist undefined. Daher der Fehler.

Aktualisiert Arbeitsbeispiel:

var App = {}; 
 

 
App.hello = Class.create({ 
 

 
    initialize: function(args) { 
 
     this.name = args.name 
 
    }, 
 

 
    sayHello: function() { 
 
     console.log('Hello, ' + this.name); 
 
    }, 
 

 
    sayGoodbye: function() { 
 
     console.log('Goodbye, ' + this.name); 
 
    } 
 

 
}); 
 

 
App.yo = Class.create(App.hello, { 
 

 
    initialize: function($super, args) { 
 
     $super(args); 
 
    }, 
 

 
    sayHello: function() { 
 
     console.log('Yo, ' + this.name); 
 
    } 
 

 
}); 
 

 
var test = new App.hello({name: 'Cameron'}); 
 
    test.sayHello(); 
 
    test.sayGoodbye(); 
 
var test2 = new App.yo({name: 'Cameron'}); 
 
    test2.sayHello(); 
 
    test2.sayGoodbye();
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js"></script>


Und in Bezug auf meinen Kommentar auf die Frage, hier ist eine ES2015 + Version nicht mit PrototypeJS:

const App = {}; 
 

 
App.hello = class { 
 
    constructor(args) { 
 
     this.name = args.name 
 
    } 
 

 
    sayHello() { 
 
     console.log('Hello, ' + this.name); 
 
    } 
 

 
    sayGoodbye() { 
 
     console.log('Goodbye, ' + this.name); 
 
    } 
 
}; 
 

 
App.yo = class extends App.hello { 
 
    sayHello() { 
 
     console.log('Yo, ' + this.name); 
 
    } 
 
}; 
 

 
const test = new App.hello({name: 'Cameron'}); 
 
     test.sayHello(); 
 
     test.sayGoodbye(); 
 
const test2 = new App.yo({name: 'Cameron'}); 
 
     test2.sayHello(); 
 
     test2.sayGoodbye();

Beachten Sie, dass wir constructor für überhaupt nicht definieren mussten, da es nichts macht. Die JavaScript-Engine wird für uns schaffen, die wie folgt aussieht:

constructor(...allArguments) { 
    super(...allArguments); 
} 
+0

Bosh! Das funktioniert perfekt, danke. – Cameron

+0

Das neue ES6-Zeug sieht gut aus ... Aber es wird nicht in IE unterstützt, oder? – Cameron

+0

@Cameron: Nein, aber Sie können mit Tools wie [Babel] (http://babeljs.io) als Teil Ihres Distributionserstellungsprozesses transpilieren. –