5

Sto cercando di ereditare le proprietà da un genitore, ma non sono chiaro sul modo corretto di farlo.Ereditarietà del prototipo in JS e come ottenere le proprietà principali

Diciamo che ho:

var Animal = function(name){ 
    this.offspring = []; 
    this.name = name; 
    return this; 
} 

Animal.prototype.createOffspring = function(name){ 
    name = name || 'Baby '+(this.offspring.length+1); 
    this.offspring.push(name); 
    return this; 
} 

Ora voglio aggiungere un sub prototipo di ereditare in modo da non dover aggiungere manualmente tutto dal genitore. Ad esempio, consente di dire che voglio aggiungere una base Cat da Animal

mi piacerebbe fare questo, come se fosse un Animal

var pet = new Cat('Kitty'); 
pet.createOffspring(); 

Senza dover manualmente per aggiungere name e createOffspring al Gatto constructor che è in realtà solo un Animal, ma con alcune altre funzionalità aggiuntive (come .meow() o qualcosa del genere).

risposta

4
// Parent 
function Animal() { 
    this.name = 'An animal'; 
} 

// Some child 
function Cat() { 
    this.speaks = 'Meow'; 
} 
// Here comes inheritence 
Cat.prototype = new Animal(); 
// Or like that 
// but don't forget to put all inheritable fields to Animal's prototype 
Cat.prototype = Object.create(Animal.prototype); 

// Let 'instanceof' work. Don't forget the following line, 
// because we eraese the info about constructor of Cat instances. 
Cat.prototype.constructor = Cat; 
// Add some custom method 
Cat.prototype.meow = function() { return this.speaks; } 

var cat = new Cat(); 
var animal = new Animal(); 

/// Some tests 
cat.name; // A animal 
animal.name; // An animal 
cat.meow(); // Meow! 
cat instanceof Cat; // true 
cat instanceof Animal; // true 

Tutto qui? (UPD: Errore con prototipo fisso) (UPD2:. Siamo spiacenti E 'tarda notte, io faccio un sacco di errori .. devo andare a dormire)


c'è anche un'altra soluzione, ma il suo Chrome, FF-specifico (forse altri):

// Animal and Cat functions from above, but 
Cat.prototype = { 
    __proto__: Animal.prototype, 
    constructor: Cat, 
    meow: function() { ... } 
} 

sembra più corto, ma not'd tentare da questo: è meglio seguire ECMAScript standart.

+0

Ho bisogno di testarlo, ma mi piacerebbe _non_ dover ripetere 'this.name' perché _all_ gli animali avranno un nome quindi,' this.name = 'Un gatto'; 'dovrebbe essere in grado di essere rimosso e 'cat.name' dovrebbe restituire' An animal' –

+0

Oh, mi dispiace. Ti ho fuorviato alla risposta sbagliata: Animal.prototype non era impostato, quindi 'cat.name' avrebbe dato un'eccezione. Il modo giusto, quando l'istanza è costruita dinamicamente, è di assegnare un oggetto ad un proto: 'Cat.prototype = Object.create (new Animal())' –

+0

Questo mi ha portato nella giusta direzione e grazie mille. Scusa ci è voluto così tanto :) Le uniche cose che sembrano essere strane sono che 'Cat.prototype.constructor = Cat;' nel codice o non funziona nello stesso modo e ottengo ancora 'true' su' instanceof' S. Anche la riga 'Object.create()' rende 'cat.name' undefined. http://jsbin.com/uhogig/edit#javascript,html –

0

Esistono diversi modelli per l'implementazione dell'ereditarietà, come descritto in JavaScript, e presentano sottili differenze rispetto al modo in cui trattano gli oggetti prototipo.

Ecco alcuni buoni riferimenti su prototype pattern e constructor pattern per iniziare.

Ed ecco uno simple implementation di ciò che hai descritto.