Javascript Closures - What are the negatives?
- by vol7ron
Question:
There seem to be many benefits to Closures, but what are the negatives (memory leakage? obfuscation problems? bandwidth increasage?)? Additionally, is my understanding of Closures correct? Finally, once closures are created, can they be destroyed?
I've been reading a little bit about Javascript Closures. I hope someone a little more knowledgeable will guide my assertions, correcting me where wrong.
Benefits of Closures:
Encapsulate the variables to a local scope, by using an internal function.
The anonymity of the function is insignificant.
What I've found helpful is to do some basic testing, regarding local/global scope:
<script type="text/javascript">
var global_text = "";
var global_count = 0;
var global_num1 = 10;
var global_num2 = 20;
var global_num3 = 30;
function outerFunc() {
var local_count = local_count || 0;
alert("global_num1: " + global_num1); // global_num1: undefined
var global_num1 = global_num1 || 0;
alert("global_num1: " + global_num1); // global_num1: 0
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = global_num2 || 0; // (notice) no definition with 'var'
alert("global_num2: " + global_num2); // global_num2: 20
global_num2 = 0;
alert("local_count: " + local_count); // local_count: 0
function output() {
global_num3++;
alert("local_count: " + local_count + "\n" +
"global_count: " + global_count + "\n" +
"global_text: " + global_text
);
local_count++;
}
local_count++;
global_count++;
return output;
}
var myFunc = outerFunc();
myFunc();
/* Outputs:
**********************
* local_count: 1
* global_count: 1
* global_text:
**********************/
global_text = "global";
myFunc();
/* Outputs:
**********************
* local_count: 2
* global_count: 1
* global_text: global
**********************/
var local_count = 100;
myFunc();
/* Outputs:
**********************
* local_count: 3
* global_count: 1
* global_text: global
**********************/
alert("global_num1: " + global_num1); // global_num1: 10
alert("global_num2: " + global_num2); // global_num2: 0
alert("global_num3: " + global_num3); // global_num3: 33
</script>
Interesting things I took out of it:
The alerts in outerFunc are only called once, which is when the outerFunc call is assigned to myFunc (myFunc = outerFunc()). This assignment seems to keep the outerFunc open, in what I would like to call a persistent state.
Everytime myFunc is called, the return is executed. In this case, the return is the internal function.
Something really interesting is the localization that occurs when defining local variables. Notice the difference in the first alert between global_num1 and global_num2, even before the variable is trying to be created, global_num1 is considered undefined because the 'var' was used to signify a local variable to that function. -- This has been talked about before, in the order of operation for the Javascript engine, it's just nice to see this put to work.
Globals can still be used, but local variables will override them. Notice before the third myFunc call, a global variable called local_count is created, but it as no effect on the internal function, which has a variable that goes by the same name. Conversely, each function call has the ability to modify global variables, as noticed by global_var3.
Post Thoughts:
Even though the code is straightforward, it is cluttered by alerts for you guys, so you can plug and play.
I know there are other examples of closures, many of which use anonymous functions in combination with looping structures, but I think this is good for a 101-starter course to see the effects.
The one thing I'm concerned with is the negative impact closures will have on memory. Because it keeps the function environment open, it is also keeping those variables stored in memory, which may/may not have performance implications, especially regarding DOM traversals and garbage collection. I'm also not sure what kind of role this will play in terms of memory leakage and I'm not sure if the closure can be removed from memory by a simple "delete myFunc;."
Hope this helps someone,
vol7ron