Question

I'm always flabbergasted by the way people try to force some form of classical inheritance into javascript. I have designed a method to inherit in some object b the prototype methods from object a, without adding prototype methods from object b to object a, and the possibility to use private variables from the object inherited from1. Now I'm curious: would you say this is really prototypal 'inheritance'? Is it a viable method? Are there pittfals to it?

Here's some example code:

Object.prototype.inheritsFrom = function(obj){
    var prototo   = this.prototype, 
        protofrom = obj.prototype;
    for (var l in protofrom) {
        if (protofrom.hasOwnProperty(l)){
            prototo[l] = protofrom[l];
        }
    }
}

function Obj1(){
    var const1 = 25;
    if (!Obj1.prototype.getConst1){
       Obj1.prototype.getConst1 = function(){
           return const1;
       }
    }
}

function Obj2(){
    var const2 = 50;
    if (!Obj2.prototype.getConst2){
       Obj2.prototype.getConst2 = function(){
           return const2;
       }
    }
    Obj2.inheritsFrom(Obj1);
}

var instanceA = new Obj1,
    instanceB = new Obj2;

Now instanceA contains method getConst1, instanceB contains methods getConst1 and getConst2, as you can see in this jsfiddle.

1 By assigning the prototype methods in the constructor function, effectively using the closure created by that.

Was it helpful?

Solution

No, that's not prototypical inheritance. In true prototypical inheritance, changes to the prototype appear in the objects that rely on that prototype. In your example, they don't, because they're only copied.

I'm not saying it may not be another useful form of inheritance for some situations, but it's not prototypical. In some sense I'm not even sure it's inheritance, although I think one could argue it either way and it doesn't really matter regardless.

Here's an example of adding to the prototype:

function Parent() {
}
Parent.prototype.foo = function() {
  display("foo!");
};

function Child() {
}
Child.prototype = new Parent();

var c = new Child();

display("[before] typeof c.foo === '" + typeof c.foo + "'");
// shows "[before] typeof c.foo === 'function'"
display("[before] typeof c.bar === '" + typeof c.bar + "'");
// shows "[before] typeof c.bar === 'undefined'"
display("Note that c.bar is currently undefined");

Parent.prototype.bar = function() {
  display("bar!");
};

display("[after] typeof c.bar === '" + typeof c.bar + "'");
// shows "[after] typeof c.bar === 'function'"
display("Now c.bar is a function");

c.foo();
c.bar();

Live copy

Note that this is not an obscure case. After all, your own code relies on changes to Object.prototype being reflected in the other things (Function) that have already derived from it.


Off-topic: Strongly recommend never adding anything to Object.prototype. It will break a huge amount of code that assumes that using for..in on a {} would yield no properties. Until you can reliably mark additions as non-enumerable (ECMAScript5 now provides a way to do that, but most implementations don't have it yet), just stay away from Object.prototype. Just a recommendation. Additionally, in your case, it doesn't make sense, because the inheritsFrom only works for Function instances, so you'd want to add it to Function.prototype instead (which is a lot less dangerous).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top