全局范围内定义的方法中的函数是否已分配给变量?
我通常不使用嵌套函数闭包,因为它们会出现垃圾收集问题 - 即它们如何在“激活对象”中保留其“词汇环境”中的周围依赖关系,并将保留在全局范围内
如果我将嵌套的函数闭包存储到函数内部的局部变量中,是否会使垃圾收集器以不同的方式处理它们?
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,听起来答案是肯定的。)
答案 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)
而不是闭包来更改它。)
但严格来说,一般而言,当你说“范围内的东西”时,你并不是指占有,除非它是具体的方法。