让我们定义一只狗:
function Dog() {}
现在让我们定义一个自我执行的函数,它将Dog作为参数传递:
(function(dogClassName) {
var someServerSideLogicResolvesClassName = "dogClassName";
//Iniate class name from the server side string
})(Dog);
经过一些谷歌搜索后,我发现我应该使用
new window["dogClassName"]();
或
new this["dogClassName"]();
但是因为它是一个范围变量,所以它不存在于全局名称空间(无窗口)中,而this
是undefined
;我不知道如何在不使用某种评估的情况下实现这一目标。
答案 0 :(得分:2)
是的,假设您正在尝试访问未全局设置的构造函数,那么问题的答案非常简单:您不能这样做。各种引擎对闭包范围的管理方式不同。如果返回的函数没有显式引用它,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';
};
}());
看看this question,在我看来是相关的,甚至是重复的。
犹豫不决的更新,但为了完整性
有一种方法可以使用变量的值作为范围链中的参考,但它确实需要 邪恶 函数的邪恶:{ {1}},您可以see in the specification,eval将保留eval('new '+ className + '()')
绑定,并重新初始化范围链。除非您使用this
因为您从ajax响应中获取构造函数名称,并且'strict mode';
很容易被利用,不会这样做! 这是理论上的一种,你可以......“。