对,假设您尝试访问未设置 global的构造函数,那么您的问题的答案很简单:您不能这样做。各种引擎对闭包的范围进行不同的管理。如果返回的函数没有显式引用它,V8 甚至可能 GC 构造函数......
没有神奇的方法可以将完整的外部范围作为对象
唯一的解决方案是创建一个命名空间对象:
(function()
{
var constructors = {Constructor1: function(){},
Constructor2: function(){}};
return function()
{
var className =getClassNameViaAjax();
if (constructors.hasOwnProperty(className))
{
return new constructors[className]();
}
if (window[className] instanceof Function)
{//fallback
return new window[className]()
}
throw className + ' Does not exist in closure, nor in global scope';
};
}());
看看这个问题,在我看来是相关的,甚至是重复的。
更新犹豫,但为了完整性
有一种方法可以使用变量的值作为作用域链中的引用,但它确实需要最邪恶的邪恶功能:eval('new '+ className + '()')正如你在规范中看到的那样,eval 将保留this绑定,并且重新初始化作用域链。除非你正在使用'strict mode';
因为你从 ajax 响应中获取构造函数名称,并且eval很容易被利用,所以不要这样做!这是一种“理论上,你可以......”的事情。