Reputation: 4873
Can someone explain why in the following function, I am able to pass an argument to a nested function? My understanding is that it has to do something with closures and scope(which I thought I had a decent understanding of), but I can seem to follow how exactly this argument is being passed.
The below function outputs 1,2 respectively. But how is the return statement doThis() getting the argument/parameter for "a"? I cant figure where/how this is accessed/passed.
function doSomething(){
var b = 1;
return function doThis(a){
console.log(b);//1
console.log(a);//2
}
}
var exec = doSomething();
exec(2);
Upvotes: 1
Views: 50
Reputation: 28958
The function doSomething()
returns another function so when you execute
var exec = doSomething();
You can think of that exec
as containing the following function
function doThis(a){ // <- takes an argument
console.log(1); // comes from the b argument in the outer scope
console.log(a); // not set yet
}
Thus when you call exec(2)
you are actually calling doThis()
with an argument 2
which becomes the value of a
.
This is a slightly simplified version. To expand on that, the doSomething()
function is described as closing over doThis()
creating a closure. Conversely, the function doThis()
is closed over or inside a closure. The closure itself is simply a limited state around the function:
function doSomething(){ // --> defines the closure
var b = 1; // variable only visible within doSomething()
return function doThis(a){ //<--> function has access to everything in doSomething(). Also defines another closure
console.log(b); // --> accesses the OUTER scope
console.log(a); // <-- comes from the INNER scope
} // <-- end INNER scope
} // --> end OUTER scope
When you execute doSomething()
the returned result still retains access to the scope within it, this is why doThis()
has access to the value b
- it's simply reachable for it. It's similar how you can do
var foo = 40;
function bar(value) {
return foo + value;
}
console.log(bar(2));
Only in this instance any other code will have acces to foo
as it's a global variable, so if you do foo = 100
in a different function, that will change the output of bar()
. A closure prevents the code inside from being reachable from outside the closure.
Upvotes: 4
Reputation: 993
When you assign var exec = doSomething();
, exec
is basically writing:
var doSomething = function(a) {
console.log(b);
console.log(a);
}
It became its own function. So passing in 2
like so exec(2)
works like any normal function except that it has the variable b
available to it because of the closure.
Upvotes: 1