1

We're all familiar with the following polyfill to create objects in JavaScript:

function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
}

One downside of this is that you will not have access to the parent's own members. Child instances will only have access to the prototype chain.

So I think the best inheritance solution is as follows:

var inherit = (function () {
  var F = function () {};
  return function (C, P) {
    F.prototype = P.prototype;
    C.prototype = new F();
    C.prototype.constructor = C;
  }
}());

function Parent(a){
    this.a = a;
}

Parent.prototype.a_proto = function(){return "a_proto";}

function Child(a,b){
    Parent.apply(this,[a]);
    this.b = b;
}

inherit(Child, Parent);

var c = new Child("a","b");
console.log(c.a); // a
console.log(c.b); // b
console.log(c.a_proto()); // a_proto
delete c.a;
console.log(c.a); // undefined

The reason why I like the above solution is because first you use the apply function to copy the parent's own members to the child's own members, therefore allowing true inheritance of the parent's own members. Second, the child also has a link to the prototype chain, and can therefore inherit prototype properties of the parent…and since we use a proxy, the child cannot modify the parent's prototype.

I was also introduced to the concept of an uber method in the book JavaScript Patterns. Basically, in the uber method the author says we "add a reference to the original parent". This is like having access to the superclass in other languages and could be handy on occasion." Here's the implementation:

function inherit(C, P) {

  var F = function () {};

  F.prototype = P.prototype;

  C.prototype = new F();

  C.uber = P.prototype;

}

I don't see how adding a reference to the original parent is good. Now the child is able to modify the parent's prototype, which is a bad thing. What is this person talking about, we now have access to superclass like in other languages? I thought using apply and the prototype chain already has given access to the superclass. Are there really any benefits to having a reference to the parent's prototype?

2540625
  • 11,022
  • 8
  • 52
  • 58
JohnMerlino
  • 3,900
  • 4
  • 57
  • 89
  • Imagine that you override an instance method of `Parent` using `Child.prototype.xxx = ...`. How would you call the super method without a direct reference to `Parent` or `Parent.prototype`? – Rob W Aug 31 '14 at 19:29
  • I'm not sure which new element you introduced here. If it is `Parent.apply(this,[a]);`, then yes, you should absolutely do that. It's like calling `super()` in Java or ES6 for example. The typical way to setup inheritance is setting the prototype via `Object.create(Parent.prototype)` and calling the parent constructor in the child constructor. See http://stackoverflow.com/a/17393153/218196 . – Felix Kling Aug 31 '14 at 19:35
  • @FelixKling my question was about "C.uber = P.prototype;" – JohnMerlino Aug 31 '14 at 19:36
  • Ah... I don't see any particular use of this, since `Child` has a reference to `Parent` anyway. The child is able to modify `Parent.prototype` already. Not that it's a good thing, but adding `uber` doesn't make it better or worse. – Felix Kling Aug 31 '14 at 19:37
  • @FelixKling you are right I do have a reference to parent. But as RobW stated in first comment, if I override an instance of Parent using Child.prototype.xxx, I will no longer have that reference to parent, no? – JohnMerlino Aug 31 '14 at 19:39
  • Via `Parent.prototype.xxx.call(this);`. You don't need `uber`. It just might be less to type. – Felix Kling Aug 31 '14 at 19:41

0 Answers0