2

While creating inheritance pattern in JS such as follows -

var Fruits = function(){};
var Apples = function(){};
Apples.prototype = new Fruits;
Apples.prototype.constructor = Apples;

Why do we change the constructor of the base class?

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
tusharmath
  • 10,622
  • 12
  • 56
  • 83
  • 2
    If by "base class" you mean `Fruits` - you don't change its constructor. – Bergi May 29 '13 at 18:28
  • 4
    My advice: forget about the words "base class". – Richard JP Le Guen May 29 '13 at 18:30
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create?redirectlocale=en-US&redirectslug=JavaScript%2FReference%2FGlobal_Objects%2FObject%2Fcreate#Classical_inheritance_with_Object.create – tusharmath May 29 '13 at 18:31
  • Please see the link above, they change the constructor. – tusharmath May 29 '13 at 18:32
  • 2
    Consider what would happen if you *didn't* re-set the `constructor` of the new prototype. All instances of `Apple` would have a `constructor` property that pointed to the `Fruit` constructor. We want it to point to `Apple` instead. Instances of `Fruit` should have a `constructor` property of `Fruit` and instances of `Apple` should have a `constructor` property of `Apple`. That's why we change the `constructor` property of `Apple`'s prototype. – apsillers May 29 '13 at 18:40
  • The "*base class*" (as you call it) is *unchanged*. Setting up `Apples` in no way changes `Fruits`. What are you referring to when you say "base class" here? – apsillers May 29 '13 at 18:44
  • @apsillers But even if you dont set the constructor and create a new object, the new object would automatically call Apple(). – tusharmath May 29 '13 at 18:46
  • Base class - > Fruits – tusharmath May 29 '13 at 18:47
  • 2
    @apsillers here is a small [fiddle](http://jsfiddle.net/5nVcT/1/). even if you don't set the constructor, your object will be an instance of Apples as well as of Fruits. It's true that the constructors of the created objects are different but it doesn't seem to make a difference. Or at least I don't see it. – basilikum May 29 '13 at 18:52
  • @basilikum Exactly my point! – tusharmath May 29 '13 at 18:53
  • @basilikum Correct, the `constructor` property is *not* a fundamental part of JS prototyping or object instantiation and is *very* rarely used. It's only there if you want to know what constructor is associated with a given instance object. If you decide to use it (or use a library that needs it), though, it's important to have it correctly set. Bergi's proposed duplicate question (and [associated duplicate](http://stackoverflow.com/q/8073867/710446)) does a fine job explaining all that. – apsillers May 29 '13 at 18:54
  • @apsillers Ok, I think I can live with that. Those are actually some good reasons. Thanks. – basilikum May 29 '13 at 19:06

2 Answers2

1

In this example apple inherits fruits constructor. The line Apples.prototype = new Fruits means any future Apple created will start as a fruit. The next line sets the constructor of Apple to fruits constructor. You could do the same thing with out the prototype but then it would only affect the one instance

aaronman
  • 18,343
  • 7
  • 63
  • 78
0

Forget about the words "base class".

In JavaScript, a function which is used as a constructor (invoked with the new keyword) can have a prototype object. The members of the prototype object can be invoked or accessed as though they were members of objects created by that constructor.

Simple example: ( http://jsfiddle.net/G2CUp/ )

var djangoFett = { // note that Django here is an object,
                   // not a constructor function and not a "class"
    shootBlaster: function() {
        alert("Blam! Blam!");
    }
};

function CloneTrooper() {
    return this;
};

CloneTrooper.prototype = djangoFett; // note that the prototype
                                     // is an object, not a "class"

var myCloneTrooper = new CloneTrooper();
myCloneTrooper.shootBlaster();

In this example we have an object djangoFett which is the prototype for objects created using the CloneTrooper constructor function. Of note is that djangoFett - the prototype for CloneTrooper - is an object, not a function or a "class".

Your code snippet is different though - your example has two constructor functions, so let's add another constructor function, to bring my code snippet more in line with yours: ( http://jsfiddle.net/r28QS/ )

function Mandalorian() {
    this.shootBlaster = function() {
        alert("Blam! Blam!");
    }
    return this;
};

var djangoFett = new Mandalorian();

function CloneTrooper() {
    return this;
};

CloneTrooper.prototype = djangoFett; // note that the prototype
                                     // is an object, not a "class"

var myCloneTrooper = new CloneTrooper();
myCloneTrooper.shootBlaster();

This time djangoFett isn't just an object literal - instead it's created by invoking the Mandalorian function while using the new keyword.

The above code snippet is very similar to the code snippet you provided in your question - I've just added a few more explicit steps along the way. Re-structuring the code to match your own a little more:

Mandalorian = function() {};
CloneTrooper = function() {};
CloneTrooper.prototype = new Mandalorian(); // note that the prototype
                                            // is an object, not a "class"

So if I then change the CloneTooper.prototype.constructor value...

// this is the same as `djangoFett.constructor = CloneTrooper`
// it does not affect the `Mandalorian` constructor function
// in any way whatsoever
CloneTooper.prototype.constructor = CloneTrooper;

...it should now be clear that this doesn't affect the the Mandalorian constructor function (the "base class") in any way. It affects only one object, which happens to be an instance of Mandalorian.

So, why do we change the constructor of the base class? The answer is we don't. We change the constructor of the prototype object. Now, why we do that is another can of worms entirely - and there are already questions on SO which address it.

Community
  • 1
  • 1
Richard JP Le Guen
  • 28,364
  • 7
  • 89
  • 119
  • 'Now, why we do that is another can of works entirely' is the main part, The link you gave was not very helpful in understanding why is it recommended in inheritence – tusharmath May 29 '13 at 19:08