I’m working on a project that involves constructing functions from other functions. I had the idea of writing a class to simplify things but I haven’t been able to get it to work without resorting to using __proto__.
Here’s basically what my vision is.
function MyFunction () {
// ...
}
var myFn = new MyFunction();
myFn(); // executes without error
myFn instanceof MyFunction; // returns true
The following code does just that using __proto__
function MyFunction () {
var fn = function () { return 'hello'; };
fn.__proto__ = this;
return fn;
}
var myFn = new MyFunction();
alert( myFn() ); // hello
alert( myFn instanceof MyFunction ); // true
Here’s something I’ve tried using valueOf
function MyFunction () {
this.fn = function () { return 'hello'; };
this.valueOf = function () { return this.fn; };
}
var myFn = new MyFunction();
alert( myFn instanceof MyFunction ); // true
alert( myFn.valueOf()() ); // hello
alert( myFn() ); // error
And here’s something else extending the function to contain all the properties of MyFunction.
function MyFunction () {
this.foo = 'hello'
var fn = function () { return 'hello'; };
for ( var i in this ) {
fn[ i ] = this[ i ];
}
return fn;
}
var myFn = new MyFunction();
alert( myFn() ); // hello
alert( myFn.foo ); // hello
alert( myFn instanceof MyFunction ); // false
I don’t want to use __proto__ because it’s non-standard. Also, this was kind of a freak idea, I’d really like to get it to work, but if it’s not possible I’ll live. But I guess my question is, is what I’d like to do possible?
Fascinating idea. I don’t believe you can do it with standard ECMAScript yet, not even using ES5.
ES5 gives us better access to and control over the prototype, including providing a means of setting the prototype when creating objects (without having to go through constructor functions) with
Object.create, but you can’t construct functions via that mechanism. And that’s what you would have to do, becauseinstanceofuses the abstract spec[[HasInstance]]method, which is currently only implemented by functions, and the function implementation of it works by seeing if the object’s underyling prototype ([[Proto]]) is===to the function’sprototypeproperty. The only standard way to set the object’s underlying prototype is to create it vianew MyFunctionor viaObject.create, and neither mechanism creates a function object.ES.next may make this possible. There’s a proposal that’s been promoted to “harmony” status (so, fairly advanced) for a “set prototype operator“,
<|, which is intended to solve many of the problems currently solved via__proto__. One of the things it’s for is “Setting the prototype of a function to something other thanFunction.prototype“. Using it (in its current form), yourMyFunctionwould look something like this:That last bit is to make it that
MyFunction.prototypeis an object with the prototypeFunction.prototype, so that functions constructed viaMyFunctionhavecall,apply,bind, etc.