Skip to content

Instantly share code, notes, and snippets.

@bmhaskar
Created December 27, 2016 12:06
Show Gist options
  • Save bmhaskar/de0d30bf6a20da91542d52218ec34ab7 to your computer and use it in GitHub Desktop.
Save bmhaskar/de0d30bf6a20da91542d52218ec34ab7 to your computer and use it in GitHub Desktop.
var genericAnimal = Object.create(null);
genericAnimal.name = 'Animal';
genericAnimal.gender = 'female';
genericAnimal.description = function() {
return 'Gender: ' + this.gender + '; Name: ' + this.name;
};
//genericAnimal is a proper object and can be used like one:
console.log(genericAnimal.description());
//Gender: female; Name: Animal
var cat = Object.create(genericAnimal);
cat.purr = function() {
return 'Purrrr!';
};
var colonel = Object.create(cat);
colonel.name = 'Colonel Meow';
var puff = Object.create(cat);
puff.name = 'Puffy';
//You can also observe that properties/methods from parents were properly carried over:
console.log(puff.description());
//Gender: female; Name: Puffy
/************** Deligation ********************/
//In JavaScript Method of implemeting inheritance is deligation
//The line below creates a new empty object with __proto__ as null.
var genericAnimal = Object.create(null);
//The code below then creates a new empty object with __proto__ set to the genericAnimal object, i.e. rodent.__proto__ points to genericAnimal.
var rodent = Object.create(genericAnimal);
rodent.size = 'S';
//The following line will create an empty object with __proto__ pointing to rodent.
var capybara = Object.create(rodent);
//capybara.__proto__ points to rodent
//capybara.__proto__.__proto__ points to genericAnimal
//capybara.__proto__.__proto__.__proto__ is null
//Since the prototype property is a reference, changing the prototype object’s properties at runtime will affect all objects
//using the prototype. For example, if we rewrote the description function or added a new function in genericAnimal after
//creating rodent and capybara, they would be immediately available for use in rodent and capybara, thanks to delegation.
/*********** "new" keyword **************/
function Person(name) {
this.name = name;
this.sayName = function() {
return "Hi, I'm " + this.name;
};
}
var adam = new Person('Adam');
function Ninja(name, weapon) {
Person.call(this, name);
this.weapon = weapon;
}
Ninja.prototype = Object.create(Person.prototype);
Ninja.prototype.constructor = Ninja;
/************ Problematic example ******************/
function Animal(){
this.offspring=[];
}
Animal.prototype.makeBaby = function(){
var baby = new Animal();
this.offspring.push(baby);
return baby;
};
//create Cat as a sub-class of Animal
function Cat() {
}
//Inherit from Animal
Cat.prototype = new Animal();
var puff = new Cat();
puff.makeBaby();
var colonel = new Cat();
colonel.makeBaby();
//What happened in the above code is very clear if you think in terms of prototypes.
//The variable offspring is created when the Animal constructor is called—and it is created in the Cat.prototype object.
//All individual objects created with the Cat constructor use Cat.prototype as their prototype,
//and Cat.prototype is where offspring resides. When we call makeBaby,
//the JavaScript engine searches for the offspring property in the Cat object and fails to find it.
//It then finds the property in Cat.prototype—and adds the new baby in the shared object that both individual Cat objects inherit from.
//So now that we understand what the problem is, thanks to our knowledge of the prototype-based system, how do we solve it?
//The solution is that the offspring property needs to be created in the object itself rather than somewhere in the prototype chain.
//There are many ways to solve it. One way is that makeBaby ensures that the object on which
//the function is called has its own offspring property:
Animal.prototype.makeBaby=function(){
var baby=new Animal();
if(!this.hasOwnProperty('offspring')){
this.offspring=[]; }
this.offspring.push(baby);
return baby;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment