Reputation: 4931
function Parent(parentName){
this.name = parentName;
}
Parent.prototype.printName = function(){
console.log(this.name);
}
var p = new Parent("Parent");
console.log(p);
function Child(parentName, childName){
Parent.call(this, parentName);
this.name = childName;
}
1. Child.prototype = Object.create(Parent.prototype);
2. Child.prototype = Parent.prototype;
var c = new Child("Parent","Child");
console.log(c);
Can someone tell me the difference between the above statements 1 & 2. In either way child object is able to call c.printName();
Upvotes: 5
Views: 909
Reputation: 1159
the difference between 1 and 2 is that
1st one you are creating a new object with the specified prototype object and properties, not shared with a parent
what Object.create(Parent.prototype)
does is it returns a new object with the prototypes of the parent, but the 2nd one you are just referencing (pointing) the child prototype to the parent prototype, so if you add a property to the child prototype say,
Child.prototype.age = function(){
console.log("parent can access this method");
}
p.age();
the parent can access this method gets printed, for classical inheritance you would want to use the first method but there are some use cases for the second method
just to expand on this post, in my opinion the best way to do inheritance is to do
// parent object
var Parent = {
firstname: "john",
getFirstName : function () {
console.log(this.firstname);
}
};
// create a child object with all the properties and methods of Parent
var child = Object.create(Parent);
// add or modify child properties
child.lastname = "doe";
child.getLastName = function () {
console.log(this.lastname);
};
// create instances of child object
baby1 = Object.create(child);
baby1.firstname = "alice";
baby1.getFirstName();
baby1.getLastName();
// to see the prototype chain
console.log("baby1 properties: ", baby1);
console.log("baby1 parent properties: ", baby1.__proto__);
console.log("baby1 grandpa properties: ", baby1.__proto__.__proto__);
very simple and no use of call or manual prototype management
Upvotes: 2
Reputation: 548
There is a big difference between the 2, one of the most confusing parts with prototypes is the fact you have prototype and proto.
Protoype is a special property of function objects, whenever you invoked a constructor function with the new keyword, the instance proto, will be the constructor prototype.
Object.create is method that allows you to create a new object, and specify it proto.
So when assigning your Child class prototype via method 1, you are giving your child class a completely new prototype object, that will inherit via prototype inheritance through the proto link, the methods of parent. This is the preferable option, as you can make modifications to the child prototype without affecting the parent prototype, since it a different object.
On the other hand on option 2 You are assigning the same prototype for both classes, they both reference the same object, thus changes to child prototype will affect parent prototype, which is usually not the desired case, nor a good practice.
Example of method 1:
Child.prototype = Object.create(Parent.prototype);
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 1');
console.log('Child.prototype = Object.create(Parent.prototype);');
Child.prototype = Object.create(Parent.prototype);
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('yay parent is still working');
Example of method 2:
Child.prototype = Parent.prototype;
function Parent(){
this.x = 0;
}
Parent.prototype.add = function(n){
this.x+= n;
return this.x;
};
var parentInstance = new Parent();
console.log('new Parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('now letss add child, which will always add 10, to the add value');
function Child(){
Parent.call(this);
}
console.log('setting child prototype via method 2');
console.log('Child.prototype = Parent.prototype;');
Child.prototype = Parent.prototype;
console.log('overriding child add function, to always add 10 to given n');
Child.prototype.add = function(n){
this.x+= n + 10;
return this.x;
}
var childInstance = new Child();
console.log('new child instance');
console.log('childInstance.add(1): ' + childInstance.add(1));
console.log('yay child is working');
console.log('now lets add again to our parent instance');
console.log('parentInstance.add(1): ' + parentInstance.add(1));
console.log('oops we broke parent');
Upvotes: 2