DEV Community

Ozoemena
Ozoemena

Posted on

Closure, Scope and lexical scope simplified

Introduction

Kunle is a thief, he stole from Iya Basira jewellery store in Lagos and managed to escape through the Seme border to Togo. The Nigerian police have been on his trail for some days now, and have gotten an intelligence report of his whereabouts, they traced him to Togo. The Nigerian police cannot enter Togo to arrest because that is outside their area of operation and so they contacted Interpol to help them make the arrest. With the help of Interpol, Nigerian police were able to arrest Kunle and bring him back to Nigeria to face the law. Now that is closure, the ability of a function to assess a variable outside its scope even when the function is executed in a different scope.
In this article, you will be learning
• what closure is

• what a scope is
• local and global variable
• Precedence between global and local variable
• Scope chain
• Lexical scoping

Scope

Scope is simply a set of rules that controls how reference to a variable is resolved. Let’s look at scope as simply an environment, a space where a function or variable can be assessed.
Local and Global Variable
Let's begin by looking at what a variable is, a variable is like a cup that you can put some water in and cover it, you can assume it to be a bowl, bucket, or box that you can store your money in and keep it. A variable can be local or global. When a variable is local, it can only be assessed by the function in which it is declared and when a variable is global, it can be assessed by all the functions within the page because it belongs to the scripting page. Let us take a look at these two examples:

function myFunction(){
      let a = 4
      return  a*a
}
Enter fullscreen mode Exit fullscreen mode

You can see that the variable a, was declared inside the myFunction and as such can only be assessed by myFunction. This makes it local as it can only be used inside the myFunction function and is hidden from other scripting code outside
Now look at this example:

let a = 4
function myFunction() {
return a*a
}
Enter fullscreen mode Exit fullscreen mode

Here you can see that the variable was declared outside the myFunction function and as such belongs to the scripting page. This makes it accessible to other functions within the page because the variable is a property of the page. It is important to note that local and global variables are not the same even if they have the same name. In a case where the local and global variables have the same name, the local variable takes precedence when the function is called, after the function execution, the local variable goes out of scope and the global variable takes precedence. This is called variable shadowing.

function myFunc() {
    let myVar = 'test';
    if (true) {
        let myVar = 'old test';
        console.log(myVar); // old test
    }
    console.log(myVar); // test
}
myFunc();
Enter fullscreen mode Exit fullscreen mode

In this code block, we can see that there are two variables with the same name, myVar. One is local, the other is global. We can see that when the variable is first consoled inside the if statement, it returns the “old test” instead of “test”, the reason is that the local variable shadowed the global variable within the if block scope. When the came variable was consoled outside the if statement, the global variable was given precedence.
We can create a variable without the declaration keyword (var, let and const). This kind of variable is always global even if they are created inside a function. While the global variable lives until the window is closed or you move to another page, a local variable is created when the function is invoked and dies when the function call finishes.
Scope Chain
From the example above we saw what global and local scope mean. Let's look at the scope chain and what it means.
Consider this code block:

let firstName = "kings"
function myName(){
   let lastName = "Badmus"
    function myLastName(){
       let address = 3
       function myProfile(){
           return console.log(`my name is ${firstName} ${lastName} and I live at ${address} blv road`)
       }
       return myProfile()
    }
    return myLastName()
}
myName()
Enter fullscreen mode Exit fullscreen mode

when this function is invoked, for the browser to give an output, it needs to look for the variables where they were defined (its lexical scope), it first looks at the myProfile function which is its local scope, if it does not find the variable, it will then look at the parent scope which is myLastName function where it finds address variable. It then looks at a higher scope to see if it can find another variable. It then looks at the next scope which is the myName function to find another variable. Finally, it looks at the global scope to see if it can find the remaining variable.
The browser can only travel from the child to the parent and not the other way around. This is called the scope chain. That is, all the scope the browser needs to travel from the innermost scope to the global scope. In this case, from myProfile() scope to myLastName() scope to myName() scope to global scope.

Lexical scope

This is simply the scope in which a variable is created or defined. The scope where a variable is defined can be different from where it is invoked or called. An item definition space its lexical scope.
Let us look at these two examples:

let car = “Innoson” 
function myCar(){
   return car
}
Enter fullscreen mode Exit fullscreen mode

In this example, the car variable is defined at the global scope so its lexical scope is its global scope and as such the myCar function can assess it since it is at the global scope.

function myCar(){
Let car = “innoson”
Return car
}
Enter fullscreen mode Exit fullscreen mode

In this case, the scope of the car variable is local and as such that is its lexical scope and can still be assessed by the myCar function since it is within its reach.
In writing code, the lexical scope needs to be put into consideration as that will determine how our program will run. This is because only code within a variable lexical scope can assess it. Let’s look at this

function showName(){
  const lastName = “Offor”
return lastName
}
function disPlayName(){
  const fullName =  “Emeka” + lastName
  return fullName
}
console.log(displayName())
Enter fullscreen mode Exit fullscreen mode

We will get an error: Uncaught ReferenceError: lastName is not defined
This is because the displayName() is trying to assess a variable outside its lexical scope. lastName has a local scope and is defined inside the showName function and as such its lexical scope is within the showName function. It cannot be assessed outside the showName function, that is the reason for the error. Let us look at it differently

function showName(){
  const lastName
return lastName
}
function disPlayName(){
  const fullName =  “Emeka” + showName()
  return fullName
}
console.log(displayName()) //Emeka Offor
Enter fullscreen mode Exit fullscreen mode

This code worked because both the showName() and displayName() are in the same lexical scope, the showName() returned the variable which can then be assessed by the displayName()

Pros and Cons of local and Global variable

It is considered best practice to declare a variable with a limited scope. This is to reduce the impact of other functions on it and its visibility within the program. However, there are cases in which a global variable has more advantage than a local variable, examples are in cases in which multiple functions are to manipulate a particular variable. Another case in which a global variable has an advantage is in a case in which we need to preserve the value of the variable, an example is a case in which we need to preserve and keep track of user login details, we store it in a global variable so that it can be made available for multiple functions. It is important to declare a global variable using const as that will keep it from being changed.
Global variables have their drawbacks in that they make our codes complex and difficult to understand and maintain and can be a source of bugs as it is being impacted by several functions. Aside from these advantages highlighted, it is advised to store our data in local variables as it makes our code easier to understand, reduces bugs and limits its scope.

Conclusion

In this article, we have been able to learn about variable scope, scope chain, lexical scope, and closure. I hope you enjoyed the article, please leave a comment for me

Top comments (0)