2012-04-19 99 views
2

我有一个构造函数,例如webapp.core.cf1或Backbone.Router。但我得到这个构造函数不作为参考,但作为一个字符串!我无法改变这个要求,结构。必须在字符串中。我怎样才能从这个新的对象,例如classfun(“Backbone.Router”)?调用字符串构造函数

function classfun (cfstr) 
{ 
    ... 
    cf = new window[cfstr](); 

如果我试试这样,我得到的错误:...不是一个构造函数。

为什么这不起作用?没有使用eval()的替代方法吗?

感谢很多提前

编辑

谢谢大家对你的答案!

谢谢你,Tronix117,这是问题!

谢谢你,本杰明舒尔特,功能!

+0

你能举一个完整的例子吗?也许,在http://jsfiddle.net上? – 2012-04-19 12:49:41

+0

以及你真正想要发生什么的示例代码? – Joseph 2012-04-19 12:50:23

+0

你怎么称呼'classfun'?你传入什么类型的变量? – Quentin 2012-04-19 12:51:53

回答

5

如果您在控制台尝试:

var A=function(a){this.test=a}; 
b = new window["A"](3); 
console.log(b.test); // return 3 

因此,这意味着,你正在试图访问的东西是不是在窗口的范围,它应该是类似的东西:window.something [” A“],如果你不知道什么是something那么你应该使用本杰明的功能,否则使用这个,因为它更快。

+0

检查窗口对象的类名属性的好东西。这解决了我遇到的问题。谢谢! – Derek 2014-07-13 04:51:32

+0

这不是他的问题,而是在非浏览器的js中呢? – catbadger 2017-09-18 16:12:23

+0

@catbadger总是有一个顶级对象,它在浏览器环境中的非浏览器环境(如node.js和'window')中通常是'global'。如果你想跨越env(浏览器+非浏览器),你可以这样做:在脚本的开始处输入'typeof global ==='undefined'&&(window.global = window)',并使用'global'随处可见。因此,在上面的例子中,你可以做'b = new global ['a'](3)'。 – Tronix117 2017-09-19 08:49:15

3

你可以这样来做(如果我理解正确的话):

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(); 

仍然可以进行优化,而应该以这种方式工作。

1
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); 

这将允许您通过名称实例化对象,并允许您根据需要传递参数。