Javascript函数更改变量范围

时间:2010-09-11 14:59:01

标签: javascript scope

我试图在匿名函数之外声明一个函数,但仍然可以访问所有匿名函数变量

下面是我正在谈论的内容。

我只需要摆脱eval。

//Used to determine where the variable is being stored
var variableScope = "global";

(function(window){
        var variableScope = 'insideFunction',
        appearingToBeGlobalFunction = function(){
                alert("This Function appears Global but really isn't");
        };
        window["addFunction"]=function(funName,fun){
                //window[funName] = fun;  Doesn't work
                eval("window[funName]="+fun+";");
        }
})(window);

addFunction("alertTest",function(){
        alert(variableScope);
        appearingToBeGlobalFunction();
});

//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();

编辑:这个问题的目标是最终保持全局范围不受大量变量影响,但仍然具有访问,设置和调用的便利,就好像它们是全局的一样。我已经得出结论,有一种方法可以做我想要的事情,但它需要在javascript中使用已弃用的功能。 这是一些示例代码,显示如何在没有eval的情况下完成上述操作。 This article讨论了如何使用“with”。

var variableScope = "global";

var customScope = {
        variableScope : 'insideFunction',
        appearingToBeGlobalFunction : function(){
                alert("This Function appears Global but really isn't");
        }
};

function alertTest(){
        with(customScope){
             alert(variableScope);
             appearingToBeGlobalFunction();
        }
};

//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();​

4 个答案:

答案 0 :(得分:2)

eval("window[funName]="+fun+";");
亲爱的主啊。

这个“有效”的原因是你将函数funalertTest)转换为一个字符串,将它放在eval参数中。

在大多数桌面浏览器中,本机JS函数的toString()结果将是一个类似于函数表达式的字符串,其中包含与原始声明相同的代码。您正在将函数转换回字符串并在新的封闭函数的上下文中重新解析该字符串,因此新函数值是相同的代码但具有不同的闭包。

但是,Function#toString不需要这样工作,in some cases it won't。依靠函数分解是不安全的;避免。

你当然只能使用eval来做这种可怕的hackery,尽管没有理由window[funName]=部分必须在eval内。 window[funName]= eval('('+fun+')');同样有效(严重)。

  

我试图在匿名函数之外声明一个函数,但仍然可以访问所有匿名函数变量

为什么你会做那种疯狂的事情?

答案 1 :(得分:2)

你无法摆脱eval,仍然希望它能够发挥作用。这是在关闭范围之后查看范围成员的唯一方法。我过去曾经弄过similar的东西,但我绝不会在任何地方使用它。考虑一个替代解决方案,无论你想要完成什么。

答案 2 :(得分:0)

你可以强制变量在全局范围内,例如,而不是var variableScope = 'insideFunction'你使用window.variableScope = 'insideFunction'

答案 3 :(得分:0)

这个问题的目标是最终保持全球范围内的大量变量,但仍然具有访问,设置和调用的便利,就好像它们是全局的一样。我已经得出结论,有一种方法可以做我想要的事情,但它需要在javascript中使用已弃用的功能。 这是一些示例代码,显示如何在没有eval的情况下完成上述操作。 This article讨论了如何使用“with”。

var variableScope = "global";

var customScope = {
        variableScope : 'insideFunction',
        appearingToBeGlobalFunction : function(){
                alert("This Function appears Global but really isn't");
        }
};

function alertTest(){
        with(customScope){
             alert(variableScope);
             appearingToBeGlobalFunction();
        }
};

//should alert "insideFunction" and "This Function appears Global but really isn't"
alertTest();​