从javascript中的字符串启动范围函数

时间:2012-11-07 09:45:23

标签: javascript

让我们定义一只狗:

function Dog() {}

现在让我们定义一个自我执行的函数,它将Dog作为参数传递:

(function(dogClassName) {

    var someServerSideLogicResolvesClassName = "dogClassName";
    //Iniate class name from the server side string
})(Dog);​

经过一些谷歌搜索后,我发现我应该使用

new window["dogClassName"]();

new this["dogClassName"]();

但是因为它是一个范围变量,所以它不存在于全局名称空间(无窗口)中,而thisundefined;我不知道如何在不使用某种评估的情况下实现这一目标。

1 个答案:

答案 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';很容易被利用,不会这样做! 这是理论上的一种,你可以......“