DEV Community

Shubham
Shubham

Posted on

Scoping in Javascript

Hi I'm writting this first post to enhanced my knowledge in Javascript. If I'm wrong somewhere than please help me to correct my mistake...
Scoping is necessary to understand to know how javascript work under the hood.

Scoping

It determine the area or region upto which your varibale, function and objects can be accessed in your code or scope determine the visibility of variable in code.

Need of Scoping

Scoping make your code secure in terms that user has access to data what is necessary at that time.Also it help to reduce bugs in program and also solve variable name resolution problem when we have two variable with same name but in different scope.

Types of Scope

GLOBAL SCOPE
Global means accessible to everywhere in program. And code that is written outside the function is come under global scope means variable define outside the function can be access anywhere in program, the variable is visible in whole program.

//GLOBAL SCOPE
var x = 10;  
console.log(x); // log '10'

function a(){
    //LOCAL SCOPE
   return x;  // 'x' is accessible here also and everywhere else in code
}
console.log(a());

Note: Global scope is only single that is created by default by javascript engine, we can't have multiple global scope in javascript.

LOCAL SCOPE
The variable or code inside the function is in local scope.Also known as function scope because the scope is local to that function and local scope only created when functions are called and each function call create new local scope for that function this give us advantage to define variable with same name in different function.

//GLOBAL SCOPE
var x = 10;  
console.log(x); // log '10'

function a(){
   //LOCAL SCOPE
   var x = 23 ;   // new local varaible 'x' with same name
   var y = 40 ;   // new local variable 'y' 
   console.log(x);  // log '23' 

}

a(); // function a() scope is created when it's call.

console.log(x); //log '10'
console.log(y); // Reference Error Unexpected identifier;

Remember we can't access variable define in function in outerScope because function scope is created when it is call and get destroyed as soon as function return.

What if I do this

var x = 10;  
console.log(x); // log '10'

function a(){
   //LOCAL SCOPE
   x = 23;      // Now we are changing the value of global variable 'x' 
   y = 40;      // new global variable 'y'
   console.log(x);  // log '23' 
}

a(); 

console.log(x); //log '23'
console.log(y); //log '43'

Whenever we assign the value to variable or create the new variable without using 'var' keyword then we are changing the value of global variable or creating a new global variable.

BLOCK SCOPE

In Javascript anything between the curly braces is termed as block.Below are the block-scope statements that contain zero or more statements inside block.
Ex:

{
  // new block scope
}

if(true){
  // new block scope
}

while(true){
  //  new block scope 
}

for(;;){
    // new block scope
}

function(){
    //new block scope
}

In case of var curly braces not define any bock-scope means variable declare using var keyword inside block are global.

var num = 1;

{//#1 block scope
    {//2 block scope 
        var num = 2; 
    }
}
console.log(num); //log '2' b/c var num=1 and  var num=2 are in same scope.

if(true){
    var num =3;
}
console.log(num); //log '3'

for(var num=4; num<5;){

}
console.log(num); //log '4'

But function scope variable are local to function means variable created inside function are bound to it, they can't be access outside the function scope.How? I have already explained above in local scope section.

Regardless of var in ES6 let and const allow to create local scope variable in block scope.Means now variables are bound to scope in which they are define they can't be access outside that scope.

const num = 1;

{//#1 block scope
    console.log(num); log '1' b/c num is global

    {//#2 block scope 
        let name = "Shubham";  
    }

    console.log(name) // ReferenceError: name is not defined
}

Remember unlike var let can't be re-declare but can be reassigned while const can only be declare once and can't be reassigned.

This is all basic about scoping in Javascript. But you should know javascript is lexical scoped language. Then here another term came lexical Scope.

LEXICAL SCOPE
Lexical scope define how variables name are resolved in case of nested blocks or nested functions or lexical scope means in group of nested block-scope(nested function) inner block has access to variable and other resources of its parent block.

    //Global Scope
    let i=1;

    {//#1 local scope

        let i=2;

        {//#2 local scope

            console.log(i); //log '2' not '1'?

        }
    } 

Now reading all this we all know that 'i' will be 2 but why have you wonder? This is because in case of lexical scoping the inner block will search for variable in its block scope first, then in outer block-scope until it reached to global scope.
Because of this hierarchy of searching variables from inner-block to outer-block a chain of scope is created known as scope chain and we get i as '2'.

In case of functions

//Global Scope
var x = 10;

function foo2(){
//Local Scope
    return x; // return '10' not '20'
}

function foo1(){
//Local Scope
    var x = 20;
    return foo2();
}

console.log(foo1()); //log '10'

Question is which 'x' value foo2() will return where it is called or where it is define. You know the answere you just have to follow scoping rule of lexical scoping.

By looking at code foo2() is called by foo1() then javascript engine look at defination of foo2() where it return 'x'.First js engine search for foo2() value in fun2() scope then in outer scope which is global scope where x is 10. That's why output is 10.

Remember in lexical scope scoping hierarchy is from top to bottom means the top most outer-block variable are available for inner-block but vice-versa in not true.

This is all about scoping.I hope I'm able to explain it well and may be I'm wrong somewhere then please tell me my mistake so I can learn from them. Thank you....

Top comments (0)