I have two situations in each testcases. I want to understand the difference and want to understand closures more.
test 1:
somefunction(someobj);
and
somefunction(function(){ return someobj; });
test 2
for(;;){
someoperations;
}
and
for(;;)(function(iterator){
someoperations;
})(iterator);
test 3:
var x = (function() {
return {};
})();
and
(function() {
//this = window
var x = function() {
//this = instance of x
this.something = somethingelse;
}
//making it global OR making it available outside closure.
return (this.x=x);
})();
I need an explanation of what is the advantage of using it in the second way in each testcase.
In javascript, the only way to create a new variable scope is in a function.
Whether or not the new scope is needed will depend entirely upon the circumstance. As such, the generic examples you presented don’t allow a definitive answer.
To give something more concrete, take we can your test 2, and apply this very common scenario where the
someoperationsis an asynchronous call like asetTimeout:The trouble is that each function created in the loop (and passed to the
setTimeout) references the sameivariable, and because it is asetTimeout, which is non-blocking, the loop finishes in its entirety before any of the functions created in the loop are ever invoked.The result is that each function will alert
4since that was where the value ofiwas left after the loop.Example: http://jsfiddle.net/Ng3rr/
On the other hand, if you invoke a function inside the loop that sets up your
setTimeout, passing the value ofito that function, then the variable referenced by each function sent tosetTimeoutwill be the localinner_i, which referenced the value that was passed into that outer invocation.(I called it
inner_ito differentiate between the two, but you could name the inner variableias well. Doing so is called variable shadowing.)Now each alert displays the value that was received during each iteration.
So as you can see, it depends entirely on the situation.
Example: http://jsfiddle.net/Ng3rr/1/
To add some contrast to the examples above, if we didn’t run any asynchronous code in the loop, the outer function would be unnecessary.
This:
Example: http://jsfiddle.net/Ng3rr/2/
…and this:
Example: http://jsfiddle.net/Ng3rr/3/
…will have identical behavior, making the outer function unnecessary.
So invoking an outer function creates a new variable scope. In that new scope, the variables will be retained by any additional nested functions created in that scope.
Also, while variables created in that scope are accessible in the functions nested in that scope, they’re unavailable outside that scope. This keeps you from polluting the surrounding scope with additional variable names.