JavaScript Variable scope

All variables and constants in JavaScript have a defined scope within which they can act.

Global variables

All variables and constants that are declared outside of functions are global:

 <!DOCTYPE html>
 <html lang="en">
 <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript Variable scope</title>
    <script>
        var a = 5;
        let b = 8;
        const c = 9;
        function displaySum(){
         
            vard = a + b + c;
            console log(d);
        }
        displaySum(); // 22
        </script>
 </head>
 <body>
    
 </body>
 </html>
 

Here the variables a and b and the constant c are global. They are available from anywhere in the program.

But the variable d is not global, since it is defined inside the function and is visible only in this function.

Defining Local Scope

To define local scope, JavaScript uses curly braces { }, which create a block of code. This block of code may be unnamed, may be named, such as a function, or may represent a conditional or looping construct. For example, defining variables in an unnamed block of code:

{
    var a = 5;
    let b = 8;
    const c = 9;
}

However, in this case, the behavior of the variable depends on how it is defined (via let) and on the type of block. var defines function-level local variables , and let defines code-block-level local variables (similarly, const defines code-block-level constants ). Let’s see what the difference is.

Function variables and constants

Variables and constants defined inside a function are only visible (that is, can be used) inside that function:

function print(){

    var a = 5;
    let b = 8;
    const c = 9;
    console.log("Function print: a =", a);
    console.log("Function print: b =", b);
    console.log("Function print: c =", c);
}
print();
console.log("Global: a =", a);  // Uncaught ReferenceError: a is not defined

The variables a and b and the constant c are local, they exist only within the function. They cannot be used outside of a function, so we get the following console output:

Function print: a= 5
Function print: b= 8
Function print: c= 9

Uncaught ReferenceError: a is not defined

Here we see that when trying to access a variable outside the function print(), the browser displays an error. At the same time, this behavior does not depend on what kind of variable it is – var or let, or if it is a constant. This behavior is the same for all variables and constants.

Local variables in code blocks, conditions, and loops

With variables that are defined in unnamed code blocks, as well as in loops and conditional constructs, the situation is a little more complicated.

var variable

A variable declared with var can be used outside of a block:

// unnamed block
{
    var a = 5;
}
console.log("a =", a);  // a = 5

// conditional construction
if(true){
    var b = 6;
}
console.log("b =", b);  // b = 6

// loop
for(var i = 0; i < 5; i++){
    var c = 7;
}
console.log("c =", c);  // c = 7

The only condition is that the block of code must fire in order to initialize the variable. So, in the example above, the condition in the if construct and in the for loop is set so that the block of these constructs will be executed. However, what if the condition is different and the block is not executed?

 
if(false){
    var b = 6;
}
console.log("b =", b);  // b = undefined

// Loop
for(var i = 1; i < 0; i++){
    var c = 7;
}
console.log("c =", c);  // c = undefined

In this case, we will again be able to access variables, only they will have the value undefined.

let variable and constants

Now let’s see how variables defined with let will behave in such a situation :

 
{
    let a = 5;
}

console.log("a =", a);  // Uncaught ReferenceError: a is not defined

In this case, we will get an error. We can use let variables defined inside a code block can only be used inside code block.

The same applies to constants:

four
{
    const b = 5;
}
console.log("b =", b);  // Uncaught ReferenceError: b is not defined

Hiding variables

What if we have two variables – one global and one local – that have the same name:

var a = 89;
function print(){

    var a = 10;
    console.log(a); // 10
}
print(); // 10

In this case, the function will use the variable z which is defined directly in the function. That is, the local variable will hide the global one. However, the exact hiding behavior depends on how the variable is defined.

Hiding the var variable

It was stated above that var defines a function-level variable. Therefore, using the var statement, we can NOT simultaneously define two variables with the same name both in a function and in a block of code in this function. If we do this, then when we declare a block-level variable, we change the value of the function-level variable:

function displayA(){
 
    var a = 20;
    
    {
        var a = 30; // Does not define a new variable, but changes the value of the function level variable a
        console.log("Block:", a);
    }
    console.log("Function:", a);
}
displayA();

Here, defining the variable inside the block will actually be equivalent to changing the value of the function-level variable, and in fact, it will be the same variable. Console output:

Block: 30
Function: 30

Hiding the let variable

As stated above, the let statement defines a code block-level variable. That is, each block of code defines a new scope in which the variable exists. The block of code where the variable is defined does not exist. Accordingly, we can simultaneously define a variable at the block level and at the function level (unlike var):

let a = 10;
function displayA(){
 
    let a = 20;
    
    {
        let a = 30;
        console.log("Block:", a);
    }
    
    console.log("Function:", a);
}

displayA();
console.log("Global:", a);

Here, inside the displayA function, a block of code is defined in which the variable a is defined (instead of an unnamed block, it could also be a block of a conditional construction or a loop). It hides the global variable and the z variable defined at the function level.

And in this case, we will get the following console output:

Block: 30
Function: 20
Global: 10

Constants

Everything that applies to the let statement also applies to the const statement, which defines block-level constants. Code blocks define the scope of constants, and constants defined on nested code blocks hide external constants of the same name:

const a = 10;
function displayA(){
 
    const a = 20;
    
    {
        const a = 30;
        console.log("Block:", a);   // 30
    }
    console.log("Function:", a);    // 20
}

displayA();
console.log("Global:", a);  // 10

Undeclared variables

If we do not use this keyword when defining a variable in a function, then such a variable will be global. For example:

function bar(){
    foo = "25";
}
bar();
console.log(foo);   // 25

Although the foo variable is not defined anywhere outside the function bar, it is nonetheless available outside the function in an external context. The only condition is that we call a function where such a variable is defined.

However, if we don’t call the function, the variable will be undefined:

 
function bar(){
    foo = "25";
}

// bar();   The function is NOT called
console.log(foo);   // error - Uncaught ReferenceError: foo is not defined

We would get the same error if we not only assigned a value to a variable but also defined it:

 
function bar(){
    var foo = "25";
}

bar();
console.log(foo);   // error - Uncaught ReferenceError: foo is not defined

Strict mode

Defining global variables in functions can lead to potential bugs. To avoid them, use strict mode or strict mode:

"use strict";
function bar(){
    foo = "25";     // Uncaught ReferenceError: foo is not defined
}
 
bar();
console.log(foo);

In this case, we will get an error SyntaxError: Unexpected identifier that says that the variable foo is not defined.

There are two ways to set strict mode:

add the “use strict” statement to the beginning of the JavaScript code, then the strict mode will be applied to all code

add the statement “use strict” to the beginning of the body of the function, then the strict mode will be applied only to this function. Function level usage example:

 
function bar(){

    "use strict";
    foo = "25";
}