I have a constructor function, for example webapp.core.cf1 or Backbone.Router. But I get this constructor function not as a reference, but as a string! I cannot change this requirement, the constr. must be in a string. How can I make a new object from this, for instance classfun("Backbone.Router")?
function classfun (cfstr)
{
...
cf = new window[cfstr]();
If I try it this way, I get the error: ... is not a constructor.
Why this does not work? Is there an alternative way without using eval()
?
Thanks a lot in advance
EDIT
Thank you all for your answers!
Thank you, Tronix117, this was the problem!!
Thank you, Benjamin Schulte, for the function!
I have a constructor function, for example webapp.core.cf1 or Backbone.Router. But I get this constructor function not as a reference, but as a string! I cannot change this requirement, the constr. must be in a string. How can I make a new object from this, for instance classfun("Backbone.Router")?
function classfun (cfstr)
{
...
cf = new window[cfstr]();
If I try it this way, I get the error: ... is not a constructor.
Why this does not work? Is there an alternative way without using eval()
?
Thanks a lot in advance
EDIT
Thank you all for your answers!
Thank you, Tronix117, this was the problem!!
Thank you, Benjamin Schulte, for the function!
Share Improve this question edited Apr 19, 2012 at 13:47 Wolfgang Adamec asked Apr 19, 2012 at 12:46 Wolfgang AdamecWolfgang Adamec 8,55413 gold badges51 silver badges77 bronze badges 3- Can you give a plete example? Perhaps, on jsfiddle? – Alexander Pavlov Commented Apr 19, 2012 at 12:49
- and also, sample code of what you really want to happen? – Joseph Commented Apr 19, 2012 at 12:50
-
How do you call
classfun
? What type of variable are you passing into it? – Quentin Commented Apr 19, 2012 at 12:51
3 Answers
Reset to default 5If you try in your console:
var A=function(a){this.test=a};
b = new window["A"](3);
console.log(b.test); // return 3
So that means, you are trying to access something which is not in the scope of window, it should rather be something like that: window.something["A"], if you don't know what is something
then you should use the function of Benjamin, otherwise use this one, because it's way faster.
You can do it this way (if I understand you correctly):
function getObjectByName(name) {
var nameParts = name.split('.');
var nameLength = nameParts.length;
var scope = window;
for (var i=0; i<nameLength; ++i) {
scope = scope[nameParts[i]];
}
return scope;
}
var ObjectClass = getObjectByName(cfstr)
new ObjectClass();
Can still be optimized, but should work this way.
ReflectUtil.newInstance = function(strClass) {
var args = Array.prototype.slice.call(arguments, 1);
var clsClass = eval(strClass);
function F() {
return clsClass.apply(this, args);
}
F.prototype = clsClass.prototype;
return new F();
};
SomeClass = function(arg1, arg2) {
// ...
}
ReflectUtil.newInstance('SomeClass', 5, 7);
This will allow you to instantiate an object by its name and allow you to pass parameters as necessary.