Javascript – How to make a callable JS object with an arbitrary prototype?

functional-programmingjavascript

Possible Duplicate:
Can a JavaScript object have a prototype chain, but also be a function?

I'm looking to make a callable JavaScript object, with an arbitrary prototype chain, but without modifying Function.prototype.

In other words, this has to work:

var o = { x: 5 };
var foo = bar(o);
assert(foo() === "Hello World!");
delete foo.x;
assert(foo.x === 5);

Without making any globally changes.

Best Solution

There's nothing to stop you from adding arbitrary properties to a function, eg.

function bar(o) {
    var f = function() { return "Hello World!"; }
    o.__proto__ = f.__proto__;
    f.__proto__ = o;
    return f;
}

var o = { x: 5 };
var foo = bar(o);
assert(foo() === "Hello World!");
delete foo.x;
assert(foo.x === 5);

I believe that should do what you want.

This works by injecting the object o into the prototype chain, however there are a few things to note:

  • I don't know if IE supports __proto__, or even has an equivalent, frome some's comments this looks to only work in firefox and safari based browsers (so camino, chrome, etc work as well).
  • o.__proto__ = f.__proto__; is only really necessary for function prototype functions like function.toString, so you might want to just skip it, especially if you expect o to have a meaningful prototype.