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.