JavaScript
2024-07-14

What is the difference between var, let and const in JavaScript?

JSvarletconst

var, let and const difference | Hero Image | s.mani.in

var, let and const are ways to declare a variable in JavaScript. var has been there since the beginning of JS, and other two were introduced in ES2015 to overcome the shortcomings of it.


This article compares the three on following factors -

  1. Variable Scope
  2. Redeclaration and Reassignment
  3. Hoisting

Variable Scope

In programming, scope refers to the part/subset of code within which a variable or a function is available to be accessed.

There are four types of scopes -

  • block scope
  • local scope (or function scope)
  • script scope
  • global scope

Note

There are few more types of scope, such as closure scope, but those are out of the "scope" of this article.

Note

During execution of the code, you can check what is the scope of a variable in the Chrome Dev Tools.

Follow these steps -

  1. Open the dev tools. Do right click and then select "Inspect"
  2. Go to the "Sources" tab
  3. In the right panel, there must be a sub-panel with the title "Scope"

You have to stop the execution of the code at that specific point where you want to check the scope of a variable. You can use "debugger".


#1 Block Scope

Code that is written between curly braces ({..}), except functions, is called as a CODE BLOCK

Following are the examples of code blocks -

{
  //code
}

if(...) {
  //code
}

for(...) {
  // code
}
JavaScript

All these are called Code Blocks.

A variable is said to have the Block Scope, when a variable declared within the code block can be accessed only inside the code block, not outside of it.



#2 Local Scope (or Function Scope)

A variable is said to have Local scope if it is declared inside a function. That variable can not be accessed outside of it.

function abc(...) {
  //variable declared inside this 
  //will have local scope
}
JavaScript


#3 Script Scope

A variable is said to have script scope if it is declared outside of any block or any function. In other words, the variable should be declared at the top level of the js file. For example -

// variables declared at this level 
// will have script scope

{
  //code
  if(..) {
    //code
  }
}

function abc(...) {
  //code
}
JavaScript

This implies that that variable can be accessed by any code block and any function in that file.

Note

One interesting thing to note is that a variable having script scope can be accessed by other js files also, given that file declaring that variable should come before the file, which accesses it, in HTML.



#4 Global Scope

A variable is said to have global scope if it is declared outside of any block or any function. It is almost same as script scope, that it can be accessed inside block, function and even in other js files, but has one small difference. Global scope variables become a part of window object.



Note

All these definition of scope will make sense with the help of examples, which are mentioned below.



Note

Variables declared with -

  • var : can have local and global scope.
  • let & const : can have block, local and script scope.

Let's understand with the help of examples


Note

Examples shown with "let" are also applicable for "const"

Example 1 : let block scope
Arrow Down White
{
  let abc = "some variable";
  debugger;
  console.log("1=>", abc);

  {
    console.log("2=>", abc);
  }
}

console.log("3 =>", abc);
JavaScript

Executing the above code in browser, we see that, at the point where the code is stopped due to "debugger" statement, the variable "abc" has "Block Scope"

Let Block Scope 1

When we checkout the console, after playing the debugger, we find that 1st and 2nd console statements were printed, but the 3rd console statement threw "Reference Error", indicating clearly that "let" variable declared inside a block can be accessed only in that block, not outside.

Let Block Scope 2


Example 2 : let local scope
Arrow Down White
function xyz() {
  let abc = "Some Variable";
  debugger;
  console.log("1 =>", abc);

  if (true) {
    console.log("2 =>", abc);
  }
}

xyz();
console.log("3 =>", abc);
JavaScript

Executing the above code in browser, we see that, at the point where the code is stopped due to "debugger" statement, the variable "abc" has "Local Scope"

Let Local Scope 1

While checking out the console, we see that 1st and 2nd console statement were printed, but 3rd console threw "Reference Error". It indicates that "let" variable declared inside of a function can be accessed inside that only, not outside.

Let Local Scope 2


Example 3 : let script scope
Arrow Down White

Let's say you two files index.js and index2.js as follows-

//index.js
let abc = "Some Variable abc";
debugger;

console.log("1 =>", abc);

function xyz() {
  console.log("2 =>", abc);

  if (true) {
    console.log("3 =>", abc);
  }
}

xyz();
JavaScript
// index2.js
console.log("4 =>", abc);
JavaScript

And let's say you have declared them in HTML in the following way

<script type="text/javascript" src="./index.js"></script>
<script type="text/javascript" src="./index2.js"></script>
HTML

Executing the above code in browser, we see that, at the point where the code is stopped due to "debugger" statement, the variable "abc" has "Script Scope"

Let Sccript Scope 1

While checking out the console, we see that all that all the console statements are printed, even the one which was there in the other file

Let Script Scope 2


Example 4 : var global scope
Arrow Down White

Let's say you two files index.js and index2.js as follows-

// index.js
if (true) {
  if (3 > 2) {
    var abc = "Some Variable ABC";
    debugger;
    console.log("1 => ", abc);
  }
  console.log("2 => ", abc);
}

console.log("3 => ", abc);
JavaScript
// index2.js
console.log("4 =>", abc);
JavaScript

Executing the above code in browser, we see that, at the point where the code is stopped due to "debugger" statement, the variable "abc" has "Global Scope". That means you can access the variable with window object as well.

Var Global Scope 1

While checking out the console, we see that all that all the console statements are printed, even the one which was there in the other file.

Var Global Scope 2


Example 5 : var local scope
Arrow Down White

Let's say you two files index.js and index2.js as follows-

// index.js

function xyz() {
  if (true) {
    if (3 > 2) {
      var abc = "Some Variable ABC";
      debugger;
      console.log("1 => ", abc);
    }
    console.log("2 => ", abc);
  }
}

xyz();
console.log("3 => ", abc);
JavaScript
// index2.js
console.log("4 =>", abc);
JavaScript

Executing the above code in browser, we see that, at the point where the code is stopped due to "debugger" statement, the variable "abc" has "Local Scope".

Var Local Scope 1

While checking out the console, we see that 1st and 2nd console statement were printed, but 3rd and 4th console statement threw Reference Error, implying that the variable abc was available only in the function, not outside.

Var Local Scope 2

Redeclaration and Reassignment

Declaration TypeDescription
varVariables declared with var can be redeclared and reassigned in its current scope.
letVariables declared with let can be redeclared in other scope than the current one. But it can be reassigned in current and any child scope.
constVariables declared with const can neither be redeclared nor reassigned any where.

Note

If you don't declare a variable with either var, let or const, then automatically JS assumes it is var type variable, and it becomes the part of global scole, even though that piece of code lies in the function.

function abc() {
  b = 3;
}
console.log(b)
// Intuition says that is should give "Reference Error"
// But it is not so.
JavaScript

Let's look at few examples

Example #1 - Redeclaration and Reassignment with var
Arrow Down White
var abc = "Hello Global";
console.log("1 =>", abc);

if (true) {
  var abc = "Hello! Global Scope";
  console.log("2 =>", abc);
}

function xyz() {
  var abc = "Hello xyz";
  console.log("3 =>", abc);
  if (true) {
    var abc = "Hello there xyz";
    console.log("4 =>", abc);
  }
}

xyz();
abc = "Nicely done!";
console.log("5 =>", abc);
JavaScript

Output of above code is as follows -

Var Redeclaration and Reassignment

We can see that we can redeclare and reassign var variable in its current scope and all its child scope.



Example #2 - Redeclaration and Reassignment with let
Arrow Down White
let abc = "Hello!";

{
  let abc = "Hello there!";

  console.log("1 =>", abc);
}

console.log("2 =>", abc);

abc = "Hello World!";

console.log("3 => ", abc);

let abc = "Good Bye";
JavaScript

In the above code, variable abc is declared with "let" in the same scope (first and last line). This piece of code will not run because we can't declare the "let" variable with the same name in the same scope.

We will get the following error -

Let Redeclaration and Reassignment

If we comment the last line, the code will work, and it implies that we can reassign the "let" variable, but we can't redeclare it in the same scope.

Let Redeclaration and Reassignment - 1


Example #3 - Redeclaration and Reassignment with const
Arrow Down White

We can assume that redeclation in the same scope will not work for const. Let's see if reassignment would work.

const abc = "Hello!";

{
  const abc = "Hello there!";
  console.log("1 =>", abc);
}

console.log("2 =>", abc);

abc = "Hello World!";
console.log("3 => ", abc);
JavaScript

Executing the above code, we will get the following error -

Const Redeclaration and Reassignment

Hence, reassignment will not work in the case of const

Hoisting

According to MDN documentation,

JavaScript Hoisting refers to the process whereby the interpreter appears to move the declaration of functions, variables, classes, or imports to the top of their scope, prior to execution of the code.

Variables declared with var are hoisted to the top of the global and local scope.

Please look at the following code and its output

console.log("1 => ", hello);

var hello = "Hello World";

console.log("2 => ", hello);
JavaScript
Var Hoisting

It implies that var variables are moved up to their scope and are assigned with undefined. And since we know that var variables can be reassigned, it takes up the value later on.

Variables declared with let and const, technically, also hoist up to their scope. But they throw the error if they are accessed before they are declared.

console.log("1 => ", hello);

let hello = "Hello World";

console.log("2 => ", hello);
JavaScript
Let Hoisting

The results are same for variable declared with const.

Conclusion

In this article, we saw the differentiating factors of var, let and const in JavaScript.

One extra important thing to note is that JavaScript sequentially searches for a variable from its current scope to higher scopes until the value is found.

Note

The order of scope is as follow -

block_scope --> local_scope --> script_scope --> global_scope
Bash

If a variable is not found in one scope, then it looks for the variable in the next scope, and so on, until the value is found. If it is not, then it returns back undefined.

Table of Content
  • Variable Scope
  • Redeclaration and Reassignment
  • Hoisting