Prototypal inheritance in JS and how to get parent properties

4.2k views Asked by At

I'm trying to have properties inherit from a parent, but I'm not clear as to the right way of doing it.

Lets say I have:

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

Now I want to add a sub prototype inherit so I don't have to manually add everything from the parent. For example, lets say I want to add a Cat based from Animal

I'd like to do this, like if it were an Animal

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

Without manually having to add name and createOffspring to the Cat constructor which is really just an Animal, but with some other added functionality (like .meow() or something).

2

There are 2 answers

4
Andrew D. On BEST ANSWER
// 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

That's it? (UPD: Error with prototype fixed) (UPD2: Sorry. It is late night, I make a lot of mistakes.. I must go sleep)


There is also another solution, but its Chrome,FF-specific (maybe others):

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

Looks shorter, but not'd be tempted by this: it's better to follow ECMAScript standart.

0
Josh Earl On

There are a number of different patterns for implementing inheritance like you're describing in JavaScript, and they have subtle differences as far as how they treat the prototype objects.

Here's are a couple of good references on the prototype pattern and the constructor pattern to get you started.

And here's a simple implementation of what you described.