Search code examples
javascriptprototypeprototype-programmingprototypal-inheritance

Prototypal inheritance in JS and how to get parent properties


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).


Solution

  • // 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.