Mark
Mark

Reputation: 4873

How JS Scope / Closures is Passing Argument

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

Answers (2)

VLAZ
VLAZ

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

Phillip Chan
Phillip Chan

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

Related Questions