从javascript中的字符串启动作用域函数
让我们定义一只狗:从javascript中的字符串启动作用域函数,javascript,Javascript,让我们定义一只狗: function Dog() {} 现在,让我们定义一个自动执行函数,将Dog作为参数传递: (function(dogClassName) { var someServerSideLogicResolvesClassName = "dogClassName"; //Iniate class name from the server side string })(Dog); 在谷歌搜索之后,我发现我应该使用 new window["dogClassNa
function Dog() {}
现在,让我们定义一个自动执行函数,将Dog作为参数传递:
(function(dogClassName) {
var someServerSideLogicResolvesClassName = "dogClassName";
//Iniate class name from the server side string
})(Dog);
在谷歌搜索之后,我发现我应该使用
new window["dogClassName"]();
或
但由于它是一个作用域变量,因此它不存在于全局名称空间(无窗口)中,
此
是未定义的
;我不知道如何在不使用某种评估的情况下实现这一点 是的,假设您试图访问的构造函数不是全局设置的,那么您的问题的答案很简单:您不能这样做。闭包的范围由不同的引擎进行不同的管理。如果返回的函数没有显式引用它,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';
};
}());
看一看,在我看来,这似乎是相关的,甚至是重复的
犹豫更新,但为了完整性有一种方法可以使用变量的值作为作用域链中的引用,但它确实需要最Evil的Evil函数:
eval('new'+className+'))
,eval将尽可能保留this
绑定,并重新初始化作用域链。除非您使用的是“严格模式”代码>
由于您是从ajax响应中获取构造函数名称的,而且eval
很容易利用,所以不要这样做!这是一种“理论上,你可以…”的东西。只是澄清一下,“构造函数”函数不是在全局范围内设置的,对吗?这更像是一种(function(){var someLocalConstructor=function(){};(function(){var className='someLocalConstructor';}())};())
情况?是的,没有一个变量在全局名称空间中(我使用requirejs,只是对代码进行了大量简化以显示用例),您能将其添加到某种容器对象吗?然后使用newcontainerObj[“dogClassName”]()
。否则你需要使用eval。对变量的引用保存在哪里?@Peeter,对变量的引用保存在容器对象中,你知道该对象的名称,只需将类名用作属性,然后你就可以使用变量的值。我最后走了这条路,但我仍然觉得奇怪,我传入回调的所有变量都没有容器/引用点。谢谢。@Peeter:有时会很烦人,但范围链被视为内部烹饪,无法访问,还是这个非官方的
(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';
};
}());