I use the following function to create instances of functions in JavaScript from an array of arguments:
var instantiate = function (instantiate) {
return function (constructor, args, prototype) {
"use strict";
if (prototype) {
var proto = constructor.prototype;
constructor.prototype = prototype;
}
var instance = instantiate(constructor, args);
if (proto) constructor.prototype = proto;
return instance;
};
}(Function.prototype.apply.bind(function () {
var args = Array.prototype.slice.call(arguments);
var constructor = Function.prototype.bind.apply(this, [null].concat(args));
return new constructor;
}));
Using the above function you can create instances as follows (see the fiddle):
var f = instantiate(F, [], G.prototype);
alert(f instanceof F); // false
alert(f instanceof G); // true
f.alert(); // F
function F() {
this.alert = function () {
alert("F");
};
}
function G() {
this.alert = function () {
alert("G");
};
}
The above code works for user built constructors like F
. However it doesn't work for native constructors like Array
for obvious security reasons. You may always create an array and then change its __proto__
property but I am using this code in Rhino so it won't work there. Is there any other way to achieve the same result in JavaScript?
You can't fully subclass an array.
However, you can use Object.create
to remove a lot of complexity from your current code (ex).
I don't think you are achieving what you are intending here. First in your F and G functions you are defining an alert function on the this object. This means every time you instantiate an object a new function object will be created and assigned to alert. This is not what you want, you need to define alert on the prototype of F and G.
function F() { }
F.prototype.alert = function() {
alert("F");
};
function G() { }
G.prototype.alert = function() {
alert("G");
};
However you still have an issue in your instantiate function. If you call it the way you have
var f = instantiate(F, [], G.prototype);
all you are doing is setting f's prototype to G.prototype, which is not what I think you want. I'm assuming that if you instantiate an F object then you would want to be able to call all of the functions defined on F.prototype, but the way things stand this is not the case.
function F() { }
F.prototype.alert = function() {
alert("F");
};
F.prototype.foo = function() {
alert("F foo");
};
function G() { }
G.prototype.alert = function() {
alert("G");
};
var f = instantiate(F, [], G.prototype);
f.foo(); // error!
The reason for the error here is like I said you just assign f's prototype to G.prototype and G.prototype does not have a foo function defined.
If you are looking to do inheritance in this way take a look at John Resig's blog he has a nice implemantation: http://ejohn.org/blog/simple-javascript-inheritance/
Also Douglas Crockford has put together some good examples: http://www.crockford.com/javascript/inheritance.html
来源:https://stackoverflow.com/questions/11490606/instantiate-javascript-functions-with-custom-prototypes