How do I create a child class of Javascript's Function class?
I would like to create a Javascript class that I can use like so:
var f = new myFunction(arg1, arg2);
f.arg1; // -> whatever was passed as arg1 in the constructor
f();
f instanceof myFunction // -> true
typeof f // -> function
I can treat it like a normal object, even adding the native Function
object to the prototype chain, but I can开发者_如何学JAVA't call it like a function:
function myFunction(arg1, arg2) {
this.arg1 = arg1;
this.arg2 = arg2;
}
myFunction.prototype = Function
var f = new myFunction(arg1, arg2); // ok
f.arg1; // ok
f(); // TypeError: f is not a function, it is object.
f instanceof myFunction // -> true
typeof f // -> object
I can have the constructor return a function, but then it's not an instance of myFunction
:
function myFunction(arg1, arg2) {
var anonFunction = function() {
};
anonFunction.arg1 = arg1;
anonFunction.arg2 = arg2;
return anonFunction;
}
var f = new myFunction(arg1, arg2); // ok
f.arg1; // ok
f(); // ok
f instanceof myFunction // -> false
typeof f // -> function
Any suggestions? I should add that I really want to avoid using new Function()
since I hate string code blocks.
First and foremost, you should probably be considering some other way of doing this, because it is unlikely to be portable. I'm just going to assume Rhino for my answer.
Second, I'm not aware of any way in Javascript of assigning a function's body after construction. The body is always specified as the object is constructed:
// Normal function definitions
function doSomething() { return 3 };
var doSomethingElse = function() { return 6; };
// Creates an anonymous function with an empty body
var doSomethingWeird = new Function;
Now, there's a non-standard Mozilla extension in the form of a __proto__
property on every object. This allows you the change the inheritance chain of any object. You can apply this to your function object to give it a different prototype after construction:
// Let's define a simple prototype for our special set of functions:
var OddFunction = {
foobar: 3
};
// Now we want a real function with this prototype as it's parent.
// Create a regular function first:
var doSomething = function() {
return: 9;
};
// And then, change it's prototype
doSomething.__proto__ = OddFunction;
// It now has the 'foobar' attribute!
doSomething.foobar; // => 3
// And is still callable too!
doSomething(); // => 9
// And some of the output from your example:
doSomething instanceof OddFunction; // => true
typeof doSomething; // => function
function Foo() { var o = function() {return "FOO"}; o.__proto__ = Foo.prototype; return o; }
(new Foo()) instanceof Foo
: true
(new Foo())()
: FOO
This isn't possible. If it should be a instance of your function then it has to be a object. Why do you want this?
I dont know why you would want to do something like this. But here's a snippet which comes close,
function MyFunction(arg1, arg2)
{
this.firstProp = arg1;
this.secondProp = arg2;
}
var f = function(arg1, arg2) {
return new MyFunction(arg1, arg2);
}(12,13);
alert("Arg1 " + f.firstProp) // 12;
alert("Arg2 " + f.secondProp) // 13;
alert(f instanceof MyFunction) // true;
Here is what I think a more javascript way of doing what you want, except it doesn't use the instanceof for objects but an inner one.
var f = function(arg1, arg2){
return {
instanceOf:arguments.callee,
arg1:arg1,
arg2:arg2
};
};
var fn = f(1, function(p){ alert(p); });
fn.arg1; // 1
fn.instanceOf === f; //true
typeof f; //function
typeof fn; //object
fn.arg2('hello'); //show alert hello
精彩评论