5

Estoy intentando que las propiedades hereden de uno de los padres, pero no tengo claro cuál es la forma correcta de hacerlo.Herencia de Prototypal en JS y cómo obtener propiedades principales

Digamos que tengo:

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; 
} 

Ahora quiero añadir un prototipo hereda sub así que no tengo que añadir manualmente todo, desde la matriz. Por ejemplo, digamos que quiero añadir una basada Cat de Animal

Me gustaría hacer esto, como si se tratara de un Animal

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

Sin tener que añadir manualmente name y createOffspring al gato constructor que es realmente solo un Animal, pero con alguna otra funcionalidad adicional (como .meow() o algo así).

Respuesta

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 

Eso es todo? (UPD: Error con el prototipo fijo) (UPD2:. En este momento es de noche tarde, lo hacen un montón de errores .. tengo que ir a dormir)


También hay otra solución, pero su Chrome, FF-específica (tal vez otros):

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

Parece más corta, pero not'd tentar por esto: es mejor seguir ECMAScript standart.

+0

Necesito probarlo, pero me gustaría _not_ no tener que volver a hacer 'this.name' porque _all_ animals tendrá un nombre, por lo tanto,' this.name = 'A cat'; 'debería poder eliminarse y 'cat.name' debería devolver' An animal' –

+0

Oh, lo siento. Le confundo a la respuesta incorrecta: Animal.prototype no fue configurado, por lo que 'cat.name' daría una excepción. La forma correcta, cuando la instancia se construye dinámicamente, es asignar un objeto a un proto: 'Cat.prototype = Object.create (new Animal())' –

+0

Esto me llevó en la dirección correcta y muchas gracias. Lo siento, tomó tanto tiempo :) Lo único que parece extraño es que 'Cat.prototype.constructor = Cat;' dentro o fuera del código funciona igual y todavía obtengo 'true' en' instanceof' s. Además, la línea 'Object.create()' hace 'cat.name' indefinido. http://jsbin.com/uhogig/edit#javascript,html –

0

Hay una serie de patrones diferentes para implementar la herencia como se describe en JavaScript, y tienen diferencias sutiles en cuanto a la forma en que tratan los objetos prototipo.

Aquí hay un par de buenas referencias en prototype pattern y constructor pattern para comenzar.

Y aquí hay un simple implementation de lo que describió.

Cuestiones relacionadas