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?
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?
2 Answers
Reset to default 7 +50You can't fully subclass an array.
However, you can use Object.create
to remove a lot of plexity 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/blog/simple-javascript-inheritance/
Also Douglas Crockford has put together some good examples: http://www.crockford./javascript/inheritance.html