Reputation: 10516
Are functions assigned to variables within methods defined in the global scope?
I typically don't use nested function closures because they present garbage collection problems -- namely how they retain surrounding dependencies from their "lexical environments" in their "activation objects" and keep them in the global scope.
If I store my nested function closures to local variables inside of functions, does that make them handled any differently by the garbage collector?
Is foo1()
essentially the same as 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();
}
(It sounds like the answer is "yes", according to Adobe's ActionScript 3.0 "Function scope" documentation.)
Upvotes: 2
Views: 82
Reputation: 389
Long story short:
No. No function definitions, nor variables, is stored in the scope. Their references can be, if declared anyhow.
At compile time, the compiler seeks for the declaration in the enclosing method scope if the closure doesn't have it.
No. GC is about checking references. If global knows about the instance via references, whether or not the instance knows about the global, the instance is safe. Otherwise, it's not.
In your example, function foo1():void { .. }
is both declaration and assignment combined. var fooVar:Function
is declaration, and = function () ...
is an assignment. Essentially, yes, except you forgot :void
at the end fooVar
.
Let me help clarify your thoughts:
(According to your question, I think you are so close to the answer, but just a little confused.)
Any method, including closure, has its own identical/independent scope. The this
keyword is one way of referencing things in other scope.
Also, the values of variables and function definitions are stored in different place of the memory, not in any scope.
Imagine you have a function like this:
private function test():void
{
new MyObject();
}
The instance of MyObject inside is never assigned, having no scope at all. If you run the method, however, it actually exists in memory, shortly before the garbage collection. (You can try a profiler to confirm that.)
Especially function definitions are fixed and no need to duplicate, they exist in static memory area.
So, anyway, conclusively, don't worry about it. They won't do any wrong in any general flash player/air runtimes.
Additionally,
Of course, in your example, you can say that myMethod()
is in its parent scope; because it is concretely declared and concretely assigned. (The compiler also fixes the this
keyword to its parent so that you cannot change it by using Function.call(thisObj)
unlike closures.)
But strictly, in general term, when you say "something in a scope", you don't mean the possession, unless it is a concrete method.
Upvotes: 0
Reputation: 7510
It's very similar to variables, but I cannot say that they are assigned to ones. It's a bit tricky here, as we cannot talk for functions as a whole, because some of them are dynamically created and others are not.
For example you cannot clear the function defined in a class with a name, like myMethod in your example (to be pretty honest I haven't tried it, but I'm 99% sure it's true, maybe someone can help me if I'm wrong). But you can clear out a closure. It's all about references. Yes, if you clear the reference to a closure it will be marked for garbage collection and thus it won't take up memory.
What is worse is not the function itself but the variables you defined, because of the scope chain of the function. If you not use closures properly, those variables keep alive and will never be garbage collected.
Here is a little bit old article about closures and scopes, which is still valid now: http://gingerbinger.com/2011/09/as3-garbage-collection-with-closures/
I hope this gives you some information, because it's not that easy to be explained :)
Upvotes: 1