Created
December 27, 2016 12:06
-
-
Save bmhaskar/de0d30bf6a20da91542d52218ec34ab7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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