var in JavaScript does not work particularly well, it confuses the heck out of beginners with it’s scope and the fact that it’s used everywhere for all concepts including constants make it difficult to identify the intent of each defined variable. ES6 introduces some new keywords that is easier to understand in terms of both scope and intent.

let keyword

The let keyword is the immediate replacement of var, although var is still supported, it is not recommended as let keyword is far superiour as it’s much easier to comprehend it’s scope.

Usage

let myVar = 1

Scope

Variables declared with the let keyword are scoped within the block that it’s been declared. This includes all blocks e.g. switch, case, if, else, function, foreach etc.

To demonstrate:

// ES6
(function() {
  console.log('ES6')
  let arr = [1,2,3,4,5]
  for(let i = 0; i < arr.length; i++) {
    console.log(i)
  }
  console.log(i) // ReferenceError, i is not defined.
})()

Because ES5’s var keyword being function scoped, let keyword can be emulated by wrapping var and everything that uses it within an IFFE.

console.log('ES5')
var arr = [1,2,3,4,5]
(function() {
  for(var i = 0; i < arr.length; i++) {
    console.log(i)
  }
})()

console.log(i) // undefined

Because let is block scoped and we no longer have to wrap things in a function to control scope, we can do things like this:

let a = "A"
{
  let b = "B"
  console.log(a) // A
  console.log(b) // B
}
console.log(a) // A
console.log(b) // Error - b is not defined

Note that b’s scope is only inside the block that it’s defined. I don’t know about you, but I think this is a pretty big deal – we don’t have to worry about leak variable scope and changing things we don’t intend to change.

const keyword

const in ES6 does not behave like it does in static compiled languages such as C# or Java, whereby a const is bound in compile time and static read-only is late-bound. const in JavaScript behaves more like the later (static read-only).

const keyword does not have an ES6 equivalent.

Usage

const myAbc = "abc"

Scope

The scope of const is the block that it’s contained in, so the scoping behaves exactly the same as the let keyword.

Declaration and Assignment

a const must always have a value assigned during declaration.

const myConst // error
myConst = 2

const does not allow assignment after declaration and assignment

const myConstant = 1
myConstant = 2 // error

If the object you assign to a const is mutable, then mutations can still happen.

class Hello {
  constructor(name = "World") {
    this.name = name
  }

  changeName(name) {
    this.name = name
  }

  sayHello() {
    console.log(`hello ${this.name}`)
  }
}
const myConstant = new Hello()
myConstant.sayHello()
myConstant.changeName("Andy")
myConstant.sayHello()

When should I use let, const and var?

If you’re using ES6, get rid of var completely, due to the issues I have raised above around it’s scope not being newbie friendly and it’s intent not being clear. Always use const unless you’re sure that the variable you want needs to be mutated ie. i in your for loop. The key here is intent. If you have to declare your function as a variable, it is unlikely to be changed, so assign it as a const unless you have very good reason for it to mutate.