2

Shape is inherited by rectangle. This inheritance can be done by many methods. Here I have used apply() and call (). When draw method is child is called, from that method draw method of base class is called again. I have done this thing in two ways. One is making the prototype draw method of base class and the other one is by using apply() and call() method.
First Method :

function Shape () {
  this.name='Shape';
  this.getName = function () {
   return this.name;
  };
  this.draw = function () {
   alert("Something");
  };
} 

function Rectangle () {
  Shape.apply(this);
  var X=this.draw;
  this.name = 'rectangle';
  this.id=500;
  this.draw = function () {
    X.call(this);
  };
}

Second Method :

function Shape () {
  this.name='Shape';
  this.id=100;
  this.getName = function () {
    return this.name;
  };
}

Shape.prototype.draw = function() {
  alert("Something");
};

function Rectangle () {
  this.name = 'rectangle';
  this.id=200;  
  this.draw = function () {
    Shape.prototype.draw.call(this);
  };
}

Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;

Both of these two methods does the similar thing (in case of providing output). I know that by using apply () and call () method I can't directly get the access of base class's prototypes. Inheritance using apply() and call() seems less complicated to me. If both are same then why don't people use apply() and call() that much ? Why do I need to use prototypes ? What problem will I face if I don't use prototypes and inherit base classes using apply() and call () ??

phtrivier
  • 13,047
  • 6
  • 48
  • 79
user1814131
  • 259
  • 4
  • 16
  • Because given that `s1 = new Shape(); s2 = new Shape();`, it's odd that `s1.draw !== s2.draw`. – Felix Kling May 09 '13 at 11:40
  • possible duplicate of [Use of 'prototype' vs. 'this' in Javascript?](http://stackoverflow.com/questions/310870/use-of-prototype-vs-this-in-javascript) – Felix Kling May 09 '13 at 11:40
  • I am not good in javascript or prototype based inheritance type things. Can you please explain a bit more ? why s1.dwar !== s2.draw ? For which case ? first one or second one ? – user1814131 May 09 '13 at 11:48
  • For the first one, because you create a new function in the constructor for each instance. – Felix Kling May 09 '13 at 11:49
  • @FelixKling actually he creates a new function in both versions. But his second version is of course an incorrect implementation of using prototypical inheritance for that method. – Alnitak May 09 '13 at 11:50
  • Shouldn't they supposed to be different ? they are different objects..they shouldn't refer to same method :S..am I wrong ? – user1814131 May 09 '13 at 12:06
  • it's perfectly normal (in fact desirable) for multiple instances of an object to share a single instance of a method (i.e. a function object). Doing otherwise wastes memory. – Alnitak May 09 '13 at 12:18

2 Answers2

2

Inheritance gives you the ability to use methods (and properties) of the base class without having to explicitly create them (or chain to them) in the derived class.

Your "alternate" method would require that every method that Shape implements be proxyed via every derived class even if that derived class does not specialise that method.

Using the prototype avoids this, because any time you call a method or access a property that doesn't exist in the derived class, the JS interpreter automatically traverses the property chain until it finds that method in a super class.

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • That means method one is not memory efficient! am I right ? If so then are there any problem in method 1 if I am not concerned about memory efficiency ? – user1814131 May 09 '13 at 11:40
  • 1
    it's not just memory efficiency, it's code efficiency. Your pattern would require massive amounts of code repetition in any substantive application. – Alnitak May 09 '13 at 11:41
0

One difference is that the 'draw' function of the Rectangle class is an instance variable ; so it will use memory in every single instance of Rectangle.

Besides, if you're using prototypes, and you don't want to change the behavior of a parent method at all (for example, in your second example, the 'draw' method of Rectangle does not do anything else than the draw method of Shape , then you don't have to redefine the method at all - when calling 'draw' on a rectangle, the runtime will climb up the prototype chain, and find the right one in Shape.

So your second example could be :

function Shape () {
  this.name='Shape';
  this.id=100;
}

Shape.prototype.getName = function () {
  return this.name;
};

Shape.prototype.draw = function() {
  alert("Something");
};

function Rectangle () {
  this.name = 'rectangle';
  this.id=200;  
}

// Notice we don't repeat "getName" since it is defined in 
// the parent class, and there is no need to do something else. 

// In case you actually want to "override" the behavior
Rectangle.prototype.draw = function () {
  Shape.prototype.draw.call(this);
  alert("Do something else than Shape");
};

Rectangle.prototype = new Shape();
Rectangle.prototype.constructor = Rectangle;
phtrivier
  • 13,047
  • 6
  • 48
  • 79
  • I did the similar code before.. But I was not sure about the use of prototype. Now I got it. Thanks a lot. Can you please explain me one more thing ? In my first example I wrote var X=this.draw; and then called the base class's draw by using X.call(this). How these two lines work ? Can you please explain ? – user1814131 May 09 '13 at 11:57
  • I would not recommend doing this, but here is how it works : in javascript, Functions are Object. So, at first, the Rectangle object has a "draw" property, that happens to be a Function. By writing `var X = this.draw`, you create a variable, X, and make it point to this Function. Later, you redefine the X property, and make it point to a new Function, that calls the Function is stored in X. The first argument to the "call" method, is the "context" in which this Function will be called. More info here : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function . – phtrivier Jun 04 '13 at 08:00