DEV Community

EidorianAvi
EidorianAvi

Posted on

Scope and Closure in JavaScript

Today I'd like to briefly go over what closure is in JavaScript and how it works.

Scope

The first thing we have to talk about when it comes to closure is scope. Scope is the level at which you have access to a point of data. There are multiple levels of scope.

  • Global Scope: This is when a variable is declared globally in a file and is able to thus be accessed at any point in that same file.

  • Local Scope: This is a functions own degree of scope. Say a variable is declared inside the function this is considered local. If you try to access this variable outside of its function or local environment you will not have access to it.

  • Outer Functions Scope: This is a big part as far as closure is concerned. If you have a function inside of a function that inner function will have access to all variables declared in the outer function.

Examples

Global:

const jediMaster = "Avar Kriss";

function greetMaster(){
   console.log(`Hello ${jediMaster}`);
}

console.log(jediMaster)
//This will log the string "Avar Kriss"

greetMaster();
//This will log the string "Hello Avar Kriss"
Enter fullscreen mode Exit fullscreen mode

The main takeaway here is since the variable jediMaster is declared at a global level in the file it is accessible both outside and inside the function.

Local:

function greetMaster(){
   const jediMaster = "Avar Kriss";
   console.log(`Hello ${jediMaster}`);
}

console.log(jediMaster);
//This will give you a Reference Error as jediMaster is not defined

greetMaster();
//This will log the string "Hello Avar Kriss"
Enter fullscreen mode Exit fullscreen mode

So now you see that the variable is only available to its local environment or the function as to where it was declared in. You cannot access it outside of the function even if in the same file.

Outer Function:


function greetMaster(){
   const jediMaster = "Avar Kriss";

   function honorMaster(){
      console.log(`Hello esteemed Jedi Master ${jediMaster}`);
   }
   honorMaster();
}

console.log(jediMaster);
//This will give you a Reference Error as jediMaster is not defined

greetMaster();
//This will log "Hello esteemed Jedi Master Avar Kriss"
Enter fullscreen mode Exit fullscreen mode

What's happening in here is that the function inside of the function still has access to the outer functions declared variable. This is due to it still being within the scope of the environment the variable was created in.

Closure

So now that we know what scope is how does that have to do with closure? Well pretty much everything.

A closure allows you to use scoping to your advantage and enclose an inner scope into a returned function allowing for encased behavior. It sounds tricky I know I'm still wrapping my head around it.

Here's a basic example of what it can look like:

function incrementBy(integer) {
    let count = 0;
    function innerFunction() {
        count += integer;
        console.log(count)
    }
    return innerFunction;
}

const firstClosure = incrementBy(3);

firstClosure();
//This will log 3 to the console

firstClosure();
//This will log 6 to the console

const secondClosure = incrementBy(5);

secondClosure();
//This will log 5 to the console

secondClosure();
//This will log 10 to the console. 

Enter fullscreen mode Exit fullscreen mode

Let's talk about it.

I created an incrementBy outer function that returns an innerFunction. That is closure to its core. Now let's walk it through step by step.

  1. First thing is I created the outer function incrementBy that takes in an integer as an argument.

  2. I created a local count variable that will start at 0 within that outer function.

  3. I created the inner function that will increment and then log the count of the outer functions scope by the argument provided.

  4. The inner function will be what the outer function returns.

  5. From there the incrementBy function is assigned to a variable firstClosure and invoked with the argument of 3. This effectively assigns the inner functions with an incrementor of 3.

  6. When you invoke the variable that again is just the inner function you will see that it will now perform the inner functions purpose and log and increment that counter by 3 every time invoked. This is where it's important to take note. We are using the outer functions variable by invoking the inner function outside of the outer function. Sounds confusing I know. That means we've created enclosed(closure) behavior with this function.

  7. You can verify this by assigning the same function incrementBy to another variable and see that it has its own count variable by invoking it.

Wrap Up

Now this example is extremely simple and can absolutely be performed without closure but it's the overall concept I'm trying to drive home and have performed it using closure. The point is that that count variable is encased and available for manipulation or use by the inner function even when the inner functions functionality is exported to an external scope.

If you have any questions or comments please feel free to reach out to me. Happy Coding!

Top comments (0)