功能是否分配给全局范围内定义的方法中的变量?

时间:2014-04-26 11:36:12

标签: actionscript-3 flash actionscript

全局范围内定义的方法中的函数是否已分配给变量

我通常不使用嵌套函数闭包,因为它们会出现垃圾收集问题 - 即它们如何在“激活对象”中保留其“词汇环境”中的周​​围依赖关系,并将保留在全局范围内

如果我将嵌套的函数闭包存储到函数内部的局部变量中,是否会使垃圾收集器以不同的方式处理它们?

foo1()fooVar()基本相同吗?

private function myMethod():void
{
    var lexicalEnvironmentVariable:Number = 5;

    function foo1():void
    {
        trace("I haz " + lexicalEnvironmentVariable);
    }

    var fooVar:Function = function()
    {
        trace("I also haz " + lexicalEnvironmentVariable);

        trace("But will I get keep my object in memory?");
    }

    foo1();
    fooVar();
}

(根据Adobe's ActionScript 3.0 "Function scope" documentation,听起来答案是肯定的。)

2 个答案:

答案 0 :(得分:1)

它与变量非常相似,但我不能说它们被分配给变量。这里有点棘手,因为我们不能谈论整个功能,因为其中一些是动态创建的,而另一些则不是。

例如,您无法清除具有名称的类中定义的函数,例如您的示例中的myMethod(说实话,我还没有尝试过,但我99%肯定它'是的,如果我错了,也许有人可以帮助我。但你可以清除一个关闭。这完全是关于参考文献。是的,如果您清除对闭包的引用,它将被标记为垃圾收集,因此它不会占用内存。

更糟糕的是,函数本身不是你定义的变量,因为函数的作用域链。如果你没有正确使用闭包,那些变量会保持活跃状态​​,永远不会被垃圾收集。

这里有一篇关于闭包和范围的旧文章,现在仍然有效:http://gingerbinger.com/2011/09/as3-garbage-collection-with-closures/

我希望这能为您提供一些信息,因为它并不容易解释:)

答案 1 :(得分:0)

长话短说:

  • 否。范围中不存储任何函数定义或变量。如果无论如何宣布,他们的引用可以是。

  • 在编译时,如果闭包没有它,编译器会在封闭方法范围内寻找声明。

  • 不。 GC是关于检查参考。如果全局通过引用了解实例,则实例是否知道全局,实例是安全的。否则,它不是。

  • 在您的示例中,function foo1():void { .. }是声明和赋值的组合。 var fooVar:Function是声明,= function () ...是作业。基本上,,除非您忘记:void fooVar


让我帮助澄清您的想法:
(根据你的问题,我认为你是如此接近答案,但只是有点困惑。)

任何方法(包括闭包)都有自己相同/独立的范围。 this关键字是引用其他范围内事物的一种方式。

此外,变量和函数定义的值存储在内存的不同位置,而不是存储在任何范围内。

想象一下,你有这样的功能:

private function test():void
{
    new MyObject();
}

永远不会分配MyObject内部的实例,根本没有范围。但是,如果运行该方法,它实际上存在于内存中,就在垃圾收集之前不久。 (您可以尝试使用分析器来确认。)

特别是函数定义是固定的,不需要复制,它们存在于静态存储区中。

所以,无论如何,最后,不要担心。他们在任何普通的Flash播放器/空中运行时都不会出错。


<强>另外,

当然,在您的示例中,您可以说myMethod()位于其父范围内;因为它是具体宣布和具体分配的。 (编译器还会将this关键字修复为其父级,以便您不能使用Function.call(thisObj)而不是闭包来更改它。)

但严格来说,一般而言,当你说“范围内的东西”时,你并不是指占有,除非它是具体的方法。