Difference between var, let and const Difference between var, let and const

A nice feature addition in ES2015 (ES6) was the introduction of let and const keywords for variable declaration. You can use var, let and const keyword interchangeably for variable declaration though it makes a difference in terms of their scope, usage and hoisting. If you are not aware of these differences then please continue to read…

Scope


Scope basically means the accessibility of a variable. Variables can have three types of scope:-

1. Global Scope

When variables is defined outside a function and accessible everywhere. All var, let and const are global scope.

2. Function Scope

Variables defined using var are function-scoped because if it is defined inside function, their visibility is limited to the function, or nested function. When you try to use it outside of the function, you’ll get an error.

function myFn() {
   var foo = 'peekaboo!';

   console.log(foo); // Prints 'peekaboo!'
}

console.log(foo); // ReferenceError: foo is not defined

3. Block Scope

Variables defined using let or const are block-scoped because if it is defined inside block of code (code between curly braces {}), their visibility is limited to the block of code, any nested block. When you try to use it outside of the block, you’ll get an error.

if (true) {
    var foo = 'peekaboo!';
    let bar = 'i see u';
    const baz = 'baby blue!';

    console.log(foo); // Prints 'peekaboo!';
    console.log(bar); // Prints 'i see u';
    console.log(baz); // Prints 'baby blue!';
}

console.log(foo); // Prints 'peekaboo!';
console.log(bar); // ReferenceError: bar is not defined
console.log(baz); // ReferenceError: baz is not defined

Usage


1. “var”

var was the only keyword for variable declaration before ES6.

var outside of a for-loop
for (var i = 0; i < 3; i++) {
  console.log(i); // Prints 0, 1 and 2
}

console.log(i);   // Prints 3

Since var is function-scoped. The variable i can be accessed outside for-loop (block of code)

var reassigning

Variable using var can be reassigned with new value and also can be redefined.

function myFn() {
    var foo = 1;
    foo = 30;
    var foo = 101;

    console.log(foo);  // Prints 101
}

myFn();

2. “let”

let outside of a for-loop
for (let i = 0; i < 3; i++) {
  console.log(i); // Prints 0, 1 and 2
}

console.log(i);   // ReferenceError: i is not defined

Since let is block-scoped. The variable i is not accessible outside for-loop (block of code)

let reassigning and redefining

Variable using let can be reassigned with new value but can not be redefined.

function myFn() {
    let foo = 1;
    foo = 30;
    let foo = 101;
    console.log(foo);  
}

myFn();
Output
Uncaught SyntaxError: Identifier 'foo' has already been declared

However, if the let variable is defined in different scopes, there will be no error.

let foo = 1;

function myFn() {
  let foo = 2;
  console.log(foo);
  
  if(true){
    let foo = 3;
    console.log(foo);
  }
}

console.log(foo);
myFn();
Output
1 2 3

Why is there no error? This is because all three instances are treated as different variables since they have different scopes.


3. “const”

The keyword const is similar to let, it’s block-scoped, however, you can’t reassign the value to it.

const PI = 3.1415;

PI = 5; // "TypeError: Assignment to constant variable.

However, new items can still be pushed into an array constant or added to an object. The following 2 snippets work without complaining because we are not trying to reassign to the variables:

const someArr = [3, 4, 5];

someArr.push(6);
const someObj = {
  dog: 'Skip',
  cat: 'Caramel',
  bird: 'Jack'
};

someObj.camel = 'Bob';

Hoisting


Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution

In case of var variables, their values are initialized with undefined in hoisting process.

console.log(foo); 
var foo = 1;
console.log(foo);

console.log(bar); 
bar = 2;
console.log(bar); 

var bar;

is interpreted as this

var foo;
var bar;

console.log(foo); // undefined
foo = 1;
console.log(foo); // 1

console.log(bar); // undefined
bar = 2;
console.log(bar); // 2
Can you guess what is output of below code snippet?
var foo = 1;

function myFun(){
  console.log(foo);
  
  var foo = 2;
}

myFun();

Have you guessed foo = 1 or foo = 2?

It’s neither one of them. It will print undefined. Let’s see how it is interpreted by the compiler in hoisting process,

var foo;
foo = 1;

function myFun(){
  
  var foo; // var hoisted and initialized with undefined
  console.log(foo); // undefined
  
  foo = 2;
}

myFun();

Just like var, let declarations also hoisted to the top but unlike var which is initialized as undefined, the let variable is not initialized. So if you try to use a let variable before declaration, you’ll get a Reference Error. const variables are similar to let variables in terms of hoisting.

console.log(foo);
let foo = 1;
Output
ReferenceError: foo is not defined
Can you guess what is output of below code snippet?
let foo = 1;

function myFun(){
  console.log(foo);
  
  let foo = 2;
}

myFun();

Have you guessed foo = undefined?

No its not. Let’s see how it is interpreted by the compiler in hoisting process,

let foo;
foo = 1;

function myFun(){
  
  let foo; // let hoisted without initialization unlike var
  console.log(foo); // ReferenceError: Cannot access 'foo' before initialization

  foo = 2;

}

myFun();

Summary


So just in case, you missed the differences, here they are :

Scope Value Update Redefine Variable Hoisting
var function scope yes yes (within scope) initialized with undefined
let block scope yes no (within block scope) but yes (outside block scope) variable not initialized
const block scope no no variable not initialized
  • var variables are function scoped whereas let and const are block scoped.
  • var variables can be updated and re-declared within its scope; let variables can be updated but not re-declared; const variables can neither be updated nor re-declared.
  • They are all hoisted to the top of their scope but while var variables are initialized with undefined, let and const variables are not initialized.
  • While var and let can be declared without being initialized, const must be initialized during declaration.

Got any question or addition? please leave a comment.

Thanks for reading.