Scope in JavaScript

Scope in JavaScript

Scope

Every variable in JavaScript has a scope, scope is basically where the variable can be accessed in the code. let and const variables are block-scoped while var variables are global/function scoped. A block a piece of code that is enclosed in {}, for eg. an if or while loop, a function or even an empty block like this one:

     {
          // Code
      }

Let's try to understand block, global and function scope in even simpler terms.

Block Scope

When a new block is created, let and const variables present inside of that block cannot be accessed outside it, they can only be accessed in that block and any children blocks that block might have. Take a look at the below code:

    let a = 'Hello'

    { // Block 1
        console.log(a) // Hello
        let b = 'Hello2'
        { // Block 2
            console.log(b); // Hello2
        }
    }   

    console.log(b); // ReferenceError

Here, a can be accessed inside Block 1 because a is present inside Block 1's parent and a child has access to it's parent's variables. Furthermore, a can also be accessed inside Block 2 because it is Block 1's child and hence can access all it's variables. However, b, which is declared inside Block 1 cannot be accessed by it's parent and gives a ReferenceError because a parent doesn't have access to variables declared inside it's children. The above logic is true for both let and const as demonstrated below:

    const a = 'Hello'

    { // Block 1
        console.log(a) // Hello
        const b = 'Hello2'
        { // Block 2
            console.log(b); // Hello2
        }
    }   

    console.log(b); // ReferenceError

Hence, we say let and const variables are block-scoped. But, in case of var variables the case is different. var variables are global/function scoped. Let's try to understand why they seem as having two scopes. First of all, var variables can be accessed from anywhere :

    var a = 'Hello'

    { // Block 1
        console.log(a) // Hello
        var b = 'Hello2'
        { // Block 2
            console.log(b); // Hello2
        }
    }   

    console.log(b); // Hello2

This is the reason they can be termed as having global scoped. However, this doesn't hold true in one case, which is, when a var variable is declared inside a function, it cannot be accessed by it's parent, even if it's parent is also a function. The below code demonstrates this:

    var a = 'globalHello'

    function parentFunction(){
        console.log(a); // globalHello
        var b = "parentHello" 
        function childFunction(){
            var c = "childHello"
            console.log(b) // parentHello
        }
        childFunction()
        console.log(c) // ReferenceError
    }

    parentFunction()

Here, a can be accessed inside parentFunction because it is declared in parentFunction's parent and similarly b can be accessed inside childFunction. But, c, which is declared in childFunction, cannot be accessed in parentFunction and trying to do so gives a ReferenceError. This why var can be termed as having both global and function scoped. In fact, a single line can describe it:

var variables declared globally have global scope while var variables declared inside a function can be accessed only within that function.