Reputation: 6854
Take this JavaScript class:
var Foo = function() {
this.bar = function() {
return 'foobar';
};
};
I can instantiate this class and call it's bar
method like this:
(new Foo).bar();
I would like to achieve the instantiation and calling of the class and it's method dynamically based of a string that represents a class and method like Foo@bar
.
I have tries the following to achieve this but receive the error Uncaught TypeError: string is not a function
:
var action = 'Foo@bar';
var classMethod = action.split('@');
(new classMethod[0]).call(classMethod[1]);
Is this even possible in JavaScript or am I going about this in the wrong way?
Upvotes: 0
Views: 105
Reputation: 288080
classMethod[0]
is a string, so you can't use it as a constructor.
Assuming Foo
is a global function,
new window[classMethod[0]]()[classMethod[1]]();
Upvotes: 0
Reputation: 2397
You could do something with eval. But I won't show that because eval is evil.
If you are willing to create an object containing the types that can be created:
var Foo = function() {
this.bar = function() {
return 'foobar';
};
};
var types = {
Foo : Foo
};
var action = 'Foo@bar';
var classMethod = action.split('@');
(new types[classMethod[0]])[classMethod[1]]();
The problem with your code was that classMethod[0]
is a string. But to use new
you need to give it a function.
In my code I make use of javascript's []
operators which accesses properties of an object using a string containing the property's name.
First I use it to get the Foo property from the types object. This is your constructor.
Then after calling the constructor, I use the []
operators again to get the bar property.
Upvotes: 1
Reputation: 1580
To access constructor by names you need to have it accessible in some collection. For example:
var Foo = function() {
this.bar = function() {
return 'foobar';
};
};
var constructors = {
Foo: Foo,
Bar: Bar
};
function instantiateAndInvoke(action) {
var classMethod = action.split('@');
var constr = constructors[classMethod[0]];
var instance = new constr();
return instance[classMethod[1]]();
}
// and then
var result = instantiateAndInvoke('Foo@bar');
Upvotes: 0
Reputation: 859
Assuming you have a Foo
object
var foo = new Foo();
You can say foo["bar"]();
to call a method called bar
on it.
Upvotes: 0