Javascript Inheritance: Prototype not Available in Instances

Just for reference. You may be dealing with Javascript inheritance and wondering how the hell you can look things up? For instance, lets say I have a Javascript class for animal, then another for cat and finally one for a tabby cat. Let’s say I’ve defined some things in each and I want to know what methods I can call? Well, if you just log out the instance of the tabby named chester, you’ll see you done have a wonderful birds eye view of the tabby cat name chester. In fact, the only thing you’ll see is that you haveĀ public instance methods and properties. Where is the “meow” function? Where is the “walk” function?

[pastacode lang=”javascript” message=”” highlight=”” provider=”manual”]

function Animal(name, legs, species) {
	this.name = name;
  this.legs = legs;
  this.species = species;
  
	var walk = function() {
    console.log("pitter patter");
  }
  
  this.walk = walk;
  
}

function Dog(name) {
	this.name = name;
  this.legs = 4;
  this.species = "Canis lupus familiaris";
  
  this.bark = function() {
		console.log("woof woof");
  }
}

function Cat(name) {
  this.name = name;
  this.legs = 4;
  this.species = "Felis catus";
  
  this.meow = function() {
    console.log("meow!");
  }
}

Dog.prototype = new Animal();
Cat.prototype = new Animal();

function Tabby(name) {
	this.name = name;
  this.legs = 4;
  
  this.lookOutWindow = function() {
    console.log("sitting by the window staring at bugs");
  }
}

Tabby.prototype = new Cat();

var chester = new Tabby("Chester");
console.log(chester);

[/pastacode]

So how can we programmatically check to see if a method or property is available for us to use? Let’s say we have a cat with two legs (that can happen), now the method “walk” should be unavailable to us. You might try and use “hasOwnProperty”, but that would return false:

[pastacode lang=”javascript” message=”” highlight=”” provider=”manual”]

// does not have a species
console.log("chester.hasOwnProperty(\"species\") = "+chester.hasOwnProperty("species"))
// but obviously its working here:
console.log(chester.species)

[/pastacode]

So what do we do? Well, there are a couple options…

If you inspect an object in chrome, you will see there’s no property name prototype. That’s because prototype is used by javascript to construct the object, once its complete it’s not available as an object itself, however, you can still call “hasOwnProperty” on “hasOwnProperty” of a prototype (that’s confusing). There is a property of the object called “__proto__” butĀ if you try to traverse it, you might find that property confusing (more here: http://stackoverflow.com/questions/9959727/proto-vs-prototype-in-javascript).

So let’s construct our methods a different way. Let’s say any time we call “new [Object]” we will also define a constructor and a parent. Then at the very least, we have something to reference inside our instances:

[pastacode lang=”javascript” message=”” highlight=”” provider=”manual”]

Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
Cat.prototype.parent = Animal.prototype;

Tabby.prototype = new Cat();
Tabby.prototype.constructor = Tabby;
Tabby.prototype.parent = Cat.prototype;

[/pastacode]

Now when we log out our instance of chester, we can see it’s fairly easy to call our parent. Now it’s fairly easy to tell how to access methods if you simple print out the object. Let’s put it all together:

function Animal(name, legs, species) {
	this.name = name;
  this.legs = legs;
  this.species = species;
  
	var walk = function() {
    console.log("pitter patter");
  }
  
  this.walk = walk;
  
}

function Dog(name) {
	this.name = name;
  this.legs = 4;
  this.species = "Canis lupus familiaris";
  
  this.bark = function() {
		console.log("woof woof");
  }
}

function Cat(name) {
  this.name = name;
  this.legs = 4;
  this.species = "Felis catus";
  
  this.meow = function() {
    console.log("meow!");
  }
}

Dog.prototype = new Animal();
Cat.prototype = new Animal();

function Tabby(name) {
	this.name = name;
  this.legs = 4;
  
  this.lookOutWindow = function() {
    console.log("sitting by the window staring at bugs");
  }
}

Tabby.prototype = new Cat();

var chester = new Tabby("Chester");
console.log(chester);


// does not have a species
console.log("chester.hasOwnProperty(\"species\") = "+chester.hasOwnProperty("species"))
// but obviously its working here:
console.log(chester.species)

// now lets check the prototype
console.log(chester.__proto__)
console.log("chester.__proto__.hasOwnProperty(\"species\") = " + chester.__proto__.hasOwnProperty("species"));
console.log(chester.__proto__.species)

// instance method
chester.lookOutWindow();

// now for the inherited methods:
// defined in cat
chester.meow();
// defined in animal
var walk = chester.walk;
walk();

See the Pen OVbLmY by Mike Newell (@newshorts) on CodePen.

Anyway, hope that clears things up a bit.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.