Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different ways of creating javascript prototype inheritance chain

Tags:

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();

like image 232
lch Avatar asked Aug 17 '16 04:08

lch


1 Answers

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');
like image 83
BarakD Avatar answered Sep 22 '22 16:09

BarakD