views:

348

answers:

4
function a () {
    return "foo";
}

a.b = function () {
    return "bar";
}

function c () { };
c.prototype = a;

var d = new c();
d.b(); // returns "bar"
d(); // throws exception, d is not a function

Is there some way for d to be a function, and yet still inherit properties from a?

+5  A: 
Eugene Lazutkin
+1  A: 
Russell Leggett
Yes, I've resorted to using a mixin. In my case, there is a small chance that a will be modified, and changes ought be reflected in d, but it isn't likely to be a big deal in practise.
Daniel Cassidy
+1  A: 

Actually, it turns out that this is possible, albeit in a non-standard way.

Mozilla, Rhino, Safari and ActionScript provide a non-standard __proto__ property, which allow changing the prototype of an object after it has been created. On these platforms, the following code is possible:

function a () {
    return "foo";
}

a.b = function () {
    return "bar";
}

function c () {
    return "hatstand";
}
c.__proto__ = a;

c(); // returns "hatstand"
c.b(); // returns "bar"; inherited from a

This might be of use to anyone who doesn't need to worry about cross-platform compatibility.

However, note that only the properties of an object can be inherited. For example:

var d = {};
d.__proto__ = a;
d.b(); // returns "bar"
d(); // throws exception -- the fact that d is inheriting from a function
     // doesn't make d itself a function.
Daniel Cassidy
A: 

Yes, it is possible if you use the __proto__ property Daniel Cassidy mentioned. The trick is to have c actually return a function that has had a attached to its prototype chain.

function a () {
    return "foo";
}

a.b = function () {
    return "bar";
}

function c () {
    var func = function() {
        return "I am a function";
    };
    func.__proto__ = a;
    return func;
}
c.prototype = a;

var d = new c();
d.b(); // returns "bar"
d(); // throws exception, d is not a function

However, you'll need to do some more tweaking of the prototype chain if you want instanceof to return better results.

d instanceof c // true
d instanceof a // false
c instanceof a // false
pr1001