4

I am learning the basics of OOP in Javascript and came across an inheritance example which is difference than what I've typically seen.

Typical:

ChildClass.prototype = new ParentClass();

Alternate Method:

function clone(object) {
  function OneShotConstructor(){}
  OneShotConstructor.prototype = object;
  return new OneShotConstructor();
}

SecondClass.prototype = clone(FirstClass.prototype);

Why would the latter be preferred when creating an object whose prototype is another object?

Cameron
  • 96,106
  • 25
  • 196
  • 225
KMcA
  • 1,155
  • 1
  • 11
  • 21
  • Does this http://stackoverflow.com/questions/2440969/javascript-functional-inheritance-with-prototypes help? – Rahul Tripathi Nov 26 '12 at 19:04
  • duplicate of [Javascript basic inheritance vs Crockford prototypical inheritance](http://stackoverflow.com/questions/11812648/javascript-basic-inheritance-vs-crockford-prototypical-inheritance) Also have a look at [Understanding Crockford's Object.create shim](http://stackoverflow.com/q/10141086/1048572) – Bergi Nov 26 '12 at 19:55

1 Answers1

3

Because you will invoke the constructor of the custom type (a.k.a. class) you are trying to inherit from. And that might have side effects. Imagine the following:

var instancesOfParentClass = 0;
function ParentClass (options) {
  instancesOfParentClass++;
  this.options = options;
}

function ChildClass () {}
ChildClass.prototype = new ParentClass();

Your counter has been incremented, but you didn't really create a useful instance of ParentClass.

Another problem, is that all instance properties (see this.options) will be present on ChildClass' prototype, and you probably don't want that.

Note: When using constructor, you might have instance properties, and shared properties. For example:

function Email (subject, body) {
  // instance properties
  this.subject = subject;
  this.body = body;
}

Email.prototype.send = function () {
  // do some AJAX to send email
};

// create instances of Email
emailBob = new Email("Sup? Bob", "Bob, you are awesome!");
emailJohn = new Email("Where's my money?", "John, you owe me one billion dollars!");

// each of the objects (instances of Email) has its own subject 
emailBob.subject // "Sup? Bob"
emailJohn.subject // "Where's my money?"

// but the method `send` is shared across instances
emailBob.send === emailJohn.send // true
Misha Reyzlin
  • 13,736
  • 4
  • 54
  • 63
  • 1
    That is correct, you shouldn't run the constructor just to setup inheritance. However there are other problems with that such as the constructor property being incorrect. I have a blog post explaining what makes for good inheritance in JS http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html – Ruan Mendes Nov 26 '12 at 19:08
  • gryxxly, I'm new to programming so excuse me for possibly sounding stupid. Can you expand on what you mean by "all instance properties will be present on ChildClass"? This example is actually from Eloquent JS, and in the book they are creating a method for the second class that will be different from the first, but will still need to be using the first method in the context of the first class. Is that related to what you're explaining? – KMcA Nov 26 '12 at 19:15
  • And so no, it's not really related to what you are talking about, that thing (if I understand you correctly) is referred to "invoke parent custom-type's method", which is sometimes needed for code-reuse (say you have just a tiny bit of custom functionality in your inherited objects, with all the rest being exactly the same as in parent custom-type). Think of particular `Email` type, that needs to add `"Sent from my iPhone"` into the end of `this.body` before being sent. – Misha Reyzlin Nov 26 '12 at 19:33
  • Thank you for expanding on that. I do see how invoking the constructor would cause problems in this case. – KMcA Nov 26 '12 at 19:41