Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/451.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何防止闭包保留javascript函数的参数?_Javascript_Closures - Fatal编程技术网

如何防止闭包保留javascript函数的参数?

如何防止闭包保留javascript函数的参数?,javascript,closures,Javascript,Closures,编辑:这个问题的上下文是,参数是正在加载的模块的源字符串,可能很大,并且有许多模块以这种方式加载,每个模块都有一个闭包,其中包含模块的原始源代码,在不需要或不需要时使用内存。 <script> function closureTest(n) { function eval_(__text) { return eval(__text); } for (var i = 0; i < n; i++) { var m = eval

编辑:这个问题的上下文是,参数是正在加载的模块的源字符串,可能很大,并且有许多模块以这种方式加载,每个模块都有一个闭包,其中包含模块的原始源代码,在不需要或不需要时使用内存。

<script>
function closureTest(n) {
    function eval_(__text) {
        return eval(__text);
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
}
</script>
<button onclick="closureTest(1000)">Run</button>
具体来说,我正在尝试修复将模块源代码泄漏到闭包中的代码。

<script>
function closureTest(n) {
    function eval_(__text) {
        return eval(__text);
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
}
</script>
<button onclick="closureTest(1000)">Run</button>

功能关闭测试(n){
函数求值(文本){
返回eval(文本);
}
对于(变量i=0;i
在上面的代码中,如果在匿名函数中放置断点,并检查存在的闭包,我们可以看到其中一个闭包包含_文本和参数[0],这些参数包含传递给eval时模块的原始源代码_

以下是上述内容的变化:

<script>
function closureTest(n) {
    function eval_() {
        return eval(arguments[0]);
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
}
</script>
<button onclick="closureTest(1000)">Run</button>

功能关闭测试(n){
函数求值(){
返回eval(参数[0]);
}
对于(变量i=0;i
在本例中,闭包不再包含_文本,但仍然包含传递给eval__的字符串的参数[0]

我能想到的最好的方法是下面的方法,它删除了eval_uu的参数。在处理它之后,一个副作用是,正在定义的模块现在也作为一个名为module的变量出现在闭包中

<script>
function closureTest(n) {
    function eval_() {
        var module = eval(arguments[0]);
        delete arguments[0];
        return module;
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
}
</script>
<button onclick="closureTest(1000)">Run</button>

功能关闭测试(n){
函数求值(){
var模块=eval(参数[0]);
删除参数[0];
返回模块;
}
对于(变量i=0;i

有没有更好的方法来防止闭包保留传递给eval_979;的参数副本?

[EDIT]完全没有抓住问题的关键。

<script>
function closureTest(n) {
    function eval_(__text) {
        return eval(__text);
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
}
</script>
<button onclick="closureTest(1000)">Run</button>
简短回答:您不能。正如您所知,闭包维护创建它的环境状态;没有办法“突破”闭包范围层次结构

当您调用
m()
时,您并不是在全局上下文中调用它,而是在一系列环境中调用它,不仅是
eval\uu
闭包,还有
closureTest
——您可以看到返回的eval'ed函数还可以访问
closureTest
中定义的
i
n
变量

因此,您不能限制或打破闭包。但是,如果您在新范围中定义了一个与以前闭包中的变量同名的新变量,您将无法直接访问该变量。因此,您的中间示例尽可能接近:

function closureTest(n) {
    function eval_() {
        return eval(arguments[0]);
    }
    for (var i = 0; i < n; i++) {
        var m = eval_("(function(){ var x = 10; return function(n) { return x+n; }; })(window);");
        m(5);
    }
 }
功能关闭测试(n){
函数求值(){
返回eval(参数[0]);
}
对于(变量i=0;i
在这里,返回的eval'ed函数无法访问
eval\uu
的参数,因为它自己的
参数已经覆盖了它(但是,它仍然可以从for循环访问
i
n
)。这意味着,从功能上讲,求值字符串不能访问传递给
eval\uu
的参数

注:

  • 是的,当您在DevTools中设置断点时,您可以检查父闭包,但这不会影响执行函数无法直接访问
    eval\ucode>的`参数[0]这一事实
  • 此外,该函数还可以使用
    arguments.callee.caller.toString()获取上层函数的字符串等等。这仍然不允许函数直接访问重新定义的变量,但认为值得一提

我不完全确定您在这里想要完成什么。为什么要删除
参数[0]
?你能提供更多的细节吗?谢谢这是一件非常奇怪的事情,我们需要在问题中提供一些上下文。为什么要直接使用eval_uu函数而不是本机eval函数?您是否计划在该函数上实现更多逻辑?您错过了问题的重点,忘记了返回的值,问题的重点是如何避免传递给eval的源代码保留在closureNice答案中,但我不想隐藏参数,我想释放它,从内存中释放它。我应该在问题中说得更清楚。