Javascript supports First Class Functions, in which case we can pass the function as an argument. An anonymous function that is defined inside an argument list of another functi
When you're unsure what the scopes of a function defined in the arguments list of a call is, notice that
fn(function x(…) { … })
is equivalent to
_temp = function x(…) { … };
fn(_temp)
Arguments are evaluated before the actual call, and they're evaluated in the same scope as the call itself is evaluated in.
The function would have access to the scope where it was defined and include any parent scope (e.g. global/window). If defined inside of another function, it would have access to any variables defined within that function. If passed in as an argument like a callback, it wouldn't have access to variables defined within the function it was passed into because it was defined outside that function and passed in as an argument.
Example:
var a = 1;
(function(callback){ //func1
//access variable in parent scope
console.log('func1', a); //outputs 1
//define a new variable within this function's scope
var b = 2;
//call our callback
callback();
//define and call a function within this function's scope
(function(){ //func3
//access variable in parent scope
console.log('func3', a); //outputs 1
//access variable in parent function scope
console.log('func3', b); //outputs 2
})();
})(function(){ //func2
//access variable in parent scope
console.log('func2', a); //outputs 1
//access variable from invoking function
console.log('func2', b); //outputs undefined
});
This would output something like:
func1 1
func2 1
func2 undefined
func3 1
func3 2
Where all the functions can see variable a
because it is in a parent scope to all functions. The argument function can't see variable b
because b
is defined in another function and the argument function was defined outside and passed in as an argument. And the function defined within the first function can see both a
and b
.
Calling an IIFE is effectively the same as first assigning the function to a variable, then then calling the function through that variable; as with any other use of anonymous functions, it's just a shortcut that avoids giving a name to the function. So:
(function(p1,p2){
p2(p1);
})(true, function(p1){ // an anonymous function passed as an argument.
m = 3;
if(p1){...}
});
is equivalent to:
var temp = function(p1,p2){
p2(p1);
};
temp(true, function(p1) {
m = 3;
if(p1){...}
});
except for the addition of temp
to the outer scope; since this variable doesn't appear anywhere else, it has no effect. The scopes of all other variables are identical in the two scenarios.