inheritance with a prototype chain

by Luke Nickerson

HTML

<h1>Inheritance with a Prototype Chain</h1>
<p>Look at the JavaScript comments and the Console (F12).</p>
<p>
    Related SO answers:<br />
<a href="http://stackoverflow.com/a/25189960/1766230">
    http://stackoverflow.com/a/25189960/1766230
    </a><br />
    <a href="http://stackoverflow.com/a/25190592/1766230">http://stackoverflow.com/a/25190592/1766230</a>
</p>

JavaScript

console.clear();
// Lifeform "Class" -- Constructor function (No prototype)
function Lifeform () {
    this.isLifeform = true;
}
	
// Animal "Class" -- Constructor function + prototype for inheritance
function Animal () {
	this.isAnimal = true;
}
Animal.prototype = new Lifeform();

// Mammal "Class" -- Constructor function + prototype for inheritance
function Mammal () {
	this.isMammal = true;
}
Mammal.prototype = new Animal();
	
// Cat "Class" -- Constructor function + prototype for inheritance
function Cat (species) {
	this.isCat = true;
	this.species = species
}
Cat.prototype = new Mammal();
	
// Make an instance object of the last "Class"
var tiger = new Cat("tiger");
	
console.log(tiger);
// Console outputs: 
// Cat {isCat: true, species: "tiger", isMammal: true, isAnimal: true, isLifeform: true} 
console.log(tiger.isCat, tiger.isMammal, tiger.isAnimal, tiger.isLifeform);
	
	// You see that all of the "is" properties are available in this object
	// But let's check to see which properties are really part of the instance object
	console.log( "tiger hasOwnProperty: "
		,tiger.hasOwnProperty("isLifeform")	// false
		,tiger.hasOwnProperty("isAnimal")	// false
		,tiger.hasOwnProperty("isMammal")	// false
		,tiger.hasOwnProperty("isCat") 		// true
	);
	// ^ Same results if you use .propertyIsEnumerable
	
	console.log( "property descriptors:\n"
		,Object.getOwnPropertyDescriptor(tiger, "isLifeform")	// undefined
		,Object.getOwnPropertyDescriptor(tiger, "isAnimal")	// undefined
		,Object.getOwnPropertyDescriptor(tiger, "isMammal") // undefined
		,Object.getOwnPropertyDescriptor(tiger, "isCat")	// object (see below)
	);
	// Console outputs: Object {value: true, writable: true, enumerable: true, configurable: true}	
	
	// New properties can be added to the prototypes of any
	// of the "classes" above and they will be usable by the instance
	Lifeform.prototype.A 	= 1;
	Animal.prototype.B 		= 2;
	Mammal.prototype.C 		= 3;
	Cat.prototype.D 		= 4;
	
	console.log(tiger.A,...