ES6 cool stuffs —var, let and const in depth

A way to explain using Groot. Character credit goes to Marvel 😄

let, const

How do you normally create new variable in Javascript? OK, i know it’s a silly question since it’s too basic to ask — we all use the “var” statement.


var firstVar; //declare firstVar width default value - undefined
var secondVar = 2; //declare and assign 2 to secondVar variable.

Just in case someone is wondering, var stands for “variable” in English (😆).

Like many modern languages, JavaScript provides us such flexibility that there is no need to decide on a specific type for our variable when we declare them.

Integer? String? Object? Function? … —var

Life is easy, until you encounter something like this:

var increment = 1;if (increment === 1){
   var increment; //re-declare increment with default value
   //Do something
}console.log(increment); //What will be printed here?

What is going on here? First of all, we will need to mention about hoisting.

A closer look — Hoisting

Hoisting, refers to the default behavior of Javascript to process and put all variables and functions declarations into memory first during phase of , regardless where they are written in code.

In more common explanation, it is the JS’s behavior of moving the declarations to the of current scope — not physically, aka no change to your code at all — and will be processed before everything else.

Take the example above, during the compile phase the code will be understood as

var increment;
var increment;increment = 1;
if (increment === 1){
}console.log(increment); //print 1

Or in another example:

var x = 0;y = 1;console.log(sumOf(x,y));
var y;function sumOf(a, b){ return a + b; }

It will be processed as:

var x;
var y;
function sumOf(a, b){ return a + b; }x = 0;
y = 1;

here JavaScript hoisting only applies to declarations, assignments. All value assignments will be processed where they are written/located in the code, resulting in:

x = 3; 
var x = 1; 

will print out undefined, 1 and NOT 1, 3 as some may thought.

In addition, we mentioned above about , which is — the scope of a declared var variable. So what about it and how does it affect var variable declaration & assignment?

What is execution context?

Execution context is the environment where Javascript code is executed/evaluated. It can be either:

  • Global — default environment
  • Functional — environment inside a function.
  • Eval — environment inside eval function.

Hence here the scope of a var variable is either or .

Any other block context — means block of code inside {} curly braces , code statement, expression, etc…—which is not from 3 defined types above will not affect the mentioned variable’s scope.

As a result, declaring a variable in a block of code statement, expression— — will be understood as declaring it at the top in the compiler/creation phase.

function testMe(){
      var x = 2;
   }   console.log(x); 
   //Still print 2 even though x is declared inside while loop

And so, that’s var. As we can see, this statement provides all the flexibility needed for developers (). So why do ES6 bother to introduce 2 more statements — let and const ? Let’s find out.


let, similar to var, declares a variable and allows (optionally) to assign any value to it. However, unlike var, it declares variable only as block scope local one.

It means the variable will be declared, existed and limited to use only inside block ({}), statement or expression and also available to its sub-block beside normal execution context (enclosing function, etc).

Therefore, in the above example, while x is not limited within while block scope like most language will do, if we replace var by let, the result will change:

function testMe(){
      let x = 2;
   }   console.log(x); //ReferenceError: x is not defined

Yup, not undefined, not null, not 2 but a ReferenceError instead.

This ensures , and we can rest assured that we won’t change by mistake any variable with same name declared somewhere before. Like in this situation:

var x = 1;{
   let x = 3;
}console.log(x); //Still 1


But wait, there is more. Since it is limited by block scope, we finally can implement private members .

var Person;{
   let name;
   Person = function(_name){ 
       name = _name;
   Person.prototype.getName = () => name;
}var person = new Person('Maya');console.log(name); //Nothing is printedconsole.log(person.getName()); //Maya

Another important difference from var is that variable hoisting doesn’t apply to let, which means during compile phase, let declaration will stay where it is and will not be processed first among other code — aka will not move to the top of context like var. Thus in executing this example,

x = 5;
y = 2;let y; 
var x;

it will yield ReferenceError again for y, but not for x.

Finally, let doesn’t create a property on global object, unlike var when being used in the global context. So no messing around with global object by accident!!! 🚀

var x = 5;
let y = 4;console.log(this.x); //5
console.log(window.x); //5
console.log(this.y); //undefined
console.log(window.y); //undefined

And unlike var, re-declaring a let variable will throw SyntaxError.

SyntaxError for x

So one thing for certain, when using letwe will have more restrictions/limitations () than the normal way of var declaration. What about const?


Let’s say, you have some data variables like templates, default messages, etc… They are meant to be used as constants — without changing.

Before ES6, one way — be careful what you write (or pray that other developer also notice and understand the naming conversion you use for constant variables).

After ES6 () we have const

const — same as let allows to declare and initialize a local block-scoped variable. Thus, it has all the restrictions of let such as:

  • Declared variables are only available to use in inside block {} of code, statement, expressions beside the normal execution context.
  • No variable hoisting applies to const
  • No property created in global object when it is used in global context.
  • Declared variable can’t be re-declared.

In addition, as you can guess, const — stands for constants:

  • Declared variable has to be initialized with a value.
const myConstants; //SyntaxError: Missing initializer in const declaration
  • Declared variable can ONLY be assigned with a value ONCE. No re-assignment — as expected for a constant value.

But one downside is that if the (object, array, etc), it still can be modified. For example:

const myConstant = {name: "Constant"};
myConstant = {name: "new Constant"}; //Error = "new Constant"; //OKconsole.log(; //new Constantconst arr = [1, 2];arr = [2,3]; //Error
arr[0] = 2; //OKconsole.log(arr); //[2,2]

In general, you probably notice the benefits these new statements bring to us by now, hence let’s sum it up.

Advantages of let and const

  • Avoid polluting our global object with unnecessary properties.
  • Avoid hidden 🐛 — such as modifying a constant value by mistake, updating wrong variables which are in different scope block but declared with same name, etc…
  • Avoid unnecessary hoisting.
  • Add more restrictions to force our code more reliable, organized and easier to read ().


Actually no matter how much advantages let and const can have against var, they are not meant to replace var but more as additional ways to provide more constraint functionalities to JavaScript and help developers saving time in code reviewing and reading.

My piece of advice, as always, is , even if it’s just a small variable — remember, if they are not handled with care in the beginning😉.


Frontend Weekly

It's really hard to keep up with all the front-end development news out there. Let us help you. We hand-pick interesting articles related to front-end development. You can also subscribe to our weekly newsletter at

Maya Shavin

Written by

Senior Front-End Developer @Cloudinary

Frontend Weekly

It's really hard to keep up with all the front-end development news out there. Let us help you. We hand-pick interesting articles related to front-end development. You can also subscribe to our weekly newsletter at