CosmoCode (Formerly TeachMeSelenium)

Understanding var, let and const in JavaScript

In this tutorial, we’ll explore the three different ways to declare a variable in JavaScript var let  const. The var available since the beginning of JavaScript. letconst added in ES6. We’ll also understand var problematic and we should letconst.

var k

Till ES5 var was the only way to declare variables in JavaScript:

//Declaring variable
var car;
//Initializing variable
car = 'Tesla';

Most of the time we do the declaration and initialization at once:

var car = 'Tesla';

Hey, I know these simple things. They are common across all programming languages.

No, they are not so simple In JavaScript scoping works differently and it causes great confusion and frustrations to beginners There is also the concept of hoisting and shadowing.

If you have no idea of “scopes”, “hoisting” or “shadowing”, don’t panic and read further.

Scope of a variable in JavaScript

The term scope in the programming world refers to the visibility of a variable or other entities. Variables are not visible outside the scope in which they are declared. In JavaScript (till ES5), the scope of a variable is either a global scope or a function scope. Before the ES6, there was no concept of block scope.

Global Scope

Any variable declared outside of a function is of global-scope, which means they can be accessed by any part of the program.

Let us see things in action:

var msg = 'Hello World';
function greet(){
  console.log(msg);
}

greet();

Output:

Hello World

In this example variable msg is defined outside of any function. So it has a global scope. We know that if any variable has a global scope, any part of the program can access it. Hence it is visible inside the function greet().

Local Scope (Function Scope)

If a variable is declared inside a function, it is NOT visible outside that function. Even if the variable is declared (using var) inside a code block (e.g,forwhile

Let us take an example:

 function greet(){
  if(true){
    var msg = 'Hello World';
  }
  console.log(msg);
}

greet();
console.log(msg);

Output:

Hello World
Uncaught ReferenceError: msg is not defined

As we can see the scope of the msg scope. Although the variable is declared inside if, it is available outside the local-block within the function. But it is not available outside the function as we can see the Uncaught ReferenceError: msg is not defined trying to access it outside the function.

It happens due to hoisting.

Hoisting

Where do you hoist a flag?

On the top of the castle.

Let us take an example to understand *hoisting* in JavaScript:

console.log(msg);
var msg = 'Hello World';

Output:

undefined

Wait…! I think we should get the following error because the variable msg was not declared when we tried to access it

Uncaught ReferenceError: msg is not defined

Well, in JavaScript, it does not matter where variables are declared within a particular scope. All variable declarations are moved to the top of their scope.

The above program was translated by the JS interpreter as:

var msg;
console.log(msg);
msg = 'Hello World';

As we can see the variable declaration was hoisted at the top of the scope, global-scope in this case. But the variable assignment was NOT hoisted. The JavaScript interpreter assigned it the default undefined Hence we got the output undefined.

The same concept would apply with function scope (local scope). All variable declarations inside a function will be at the top of the function, no matter where they are declared in the function.

 function greet(){
  if(true){
    var msg = 'Hello World';
  }
  console.log(msg);
}

greet();
console.log(msg);

The above program was translated by JavaScript interpreter as if var msg was hoisted at the top of the function although it is declared inside the if block.

 function greet(){
  var msg;
  if(true){
    msg = 'Hello World';
  }
  console.log(msg);
}

greet();
console.log(msg);

Hence we get the output – Hello World

Shadowing

If we declare a local variable and a global variable with the same name, the local variable will take precedence when it is referred inside a function. It is called shadowing, the inner variable shadows the outer variable. The Javascript interpreter searches for the variable at the innermost scope and continues until the first match is found.

var msg = 'Hello ';
var name = 'John';
function greet(){
  var msg = 'Julia';
  if(true){
    console.log(msg + name); //Hello Julia
  }
}

greet();

The moment if is executed by the JavaScript interpreter, it looks for the msg the local scope. As it is found there, it uses the local scope variable, even if the same variable is declared in the outer scope as well. name is not found in the inner scope so the JS interpreter tries to find it in the outer scope and it is found.

Scoping and Hoisting works the same for functions as it works with variables.

Issues with var

No that we have understood different concepts related to var , let us discuss the issues with var and why you should avoid using it.

Let us take an example:

var greetings = 'Hello John';

function greet() {
  console.log(greetings); // undefined
  if (true) {
    var greetings = 'Hello Julia';
    console.log(greetings); //Hello Julia
  }
  console.log(greetings); //Hello Julia
}

greet();

If you are coming from another programming like Java, Python, C# , you must be thinking “what the heck”. Don’t you think as greetings is a global variable the first output should Hello John And the third output should be Hello John because although inside if we have declared the same greetings should not be visible outside if?

Incorrect!

We just learned about scoping, hoisting and shadowing in JavaScript. We know there is no concept of block scope in JavaScript(till ES5). Let us apply these learnings for the above example.

When the JavaScript interpreter encounters the variable declaration greetings the if, it hoisted the variable declaration at the top of the function. But only the declaration is hoisted, not initialization. The variable has the default undefined the JavaScript interpreter assigns while declaration. When greetings is referred inside the first print statement, due to *shadowing* the JavaScript interpreter used the inner declaration of greetings, not the global one. But since the inner declaration greetings not initialized yet, it printed its default undefined

Again, the same concept of hoisting and shadowing got applied in the third output. The interpreter took the function-scoped declaration greetings The only difference is this timegreetings already inside if.

As we can see variables declared var confusing and prone to introduce bugs in the program, if not written with at most care. And that is the reason you should never var declare variables in your program. Always use let or const to declare variables.

let keyword in ES6

The ES6 specification addressed these issues with JavaScript and introduced **block scoping** with a new keyword let.

Let us take the same example as the previous one with a change – replacing var with let keyword :

let greetings = 'Hello John';

function greet() {
  console.log(greetings); //Hello John
  if (true) {
    let greetings = 'Hello Julia';
    console.log(greetings); //Hello Julia
  }
  console.log(greetings); //Hello John
}

greet();

As we see the output is more predictable with let. The first time greetings in the print statement, it took the global value because it was not yet declared locally. The JavaScript interpreter declared the second instance greeting the local scope inside if. It retains the local Hello Julia if. But outside if in where the variable was declared, the greetings is not visible to the interpreter. Hence it took the global declaration in the third print statement.

As we see the let keyword is behaving similar to most of the other programming languages and is having *block scope*. That is the reason we should “mostly” let to declare variables in JavaScript and never var

const keyword in ES6

I hope you have noticed the earlier statement – we should “mostlylet. We have used mostly because when we have variables that are never going to change their value, we should declare them const. It is a good safety feature because if any part of the program to change the value of the variable, the JavaScript interpreter will raise an Exception.

Let us see things in action:

function greet() {
  const greetings = 'Hello World';
  if (true) {
    greetings = 'Hello Julia';
    console.log(greetings);
  }
}

greet();

If we run this code, the JavaScript interpreter will raise an Exception where we try to change the value of const variable greetings.

Uncaught TypeError: Assignment to constant variable.
    at greet (<anonymous>:4:15)
    at <anonymous>:9:1

There is no other difference between let and const

Conclusion

We hope this tutorial gave you a good understanding of all the three ways to declare variables in JavaScript. We discussed var not have block scope, it is bug prone and we should never use it. We should use S6’s let const. We also learned that we should const we want to restrict a variable so that it never changes its value and remain .

Exit mobile version