JavaScript: 3 Ways of Variable Declaration
var
let
const
Before ECMAScript 6 (ES6 or the latest version of the language specification standard), var was the only way way to declare a variable. ES6 has since given us two more options to declare variables: let and const. As a beginner, I was often confused about how and when to use each of these, so I figured I would share my findings in case anyone else found themselves needing clarification.
Var and let seem very similar at first glance, but they are not truly synonymous. One big difference between the two is that of scope. The var keyword defines a variable globally or locally to an entire function regardless of block scope. By contrast, let allows you to declare variables that are limited in scope to the block, statement, or expression on which it is used.Â
To further expand on this, variables declared with var are either function-wide or global and cannot be block-local or loop-local. Var ignores code blocks and so pierces through them. Because var can declare variables globally or inside a function, when the variableâs value is reassigned inside a block later, the original value of var updates. See below for an example:
function() { Â Â var x = 1; Â Â console.log(x) // 1 Â Â if(true) { Â Â Â Â var x = 2 Â Â Â Â console.log(x) //2 Â Â } Â Â console.log(x) //2 }
On the other hand, since let limits the value of a variable within a block scope, the original value will be left unchanged as illustrated below:
function() { Â Â let x = 1; Â Â console.log(x) // 1 Â Â if(true) { Â Â Â Â let x = 2 Â Â Â Â console.log(x) //2 Â Â } Â Â console.log(x) // 1 }
Var declarations are also processed at the beginning of a function (or script for globals) unless the definition is in a nested function. This is called hoisting because all var are hoisted or raised to the top of the function. Even if an âifâ branch never executes, the var inside it is processed in the beginning of the function. Although these declarations are processed at the start of function execution, assignments are not hoisted and work at the exact place they appear. This means that although all var declarations can be referenced at any place since they are processed at function start, they are undefined until assignment.Â
Variables declared with let are not subject to variable hoisting which means they cannot be referenced before the block where initialization of that variable occurs (without receiving a ReferenceError). The variable is in what we call a temporal dead zone from the start of the block until the initialization is processed. Let variables may be reassigned (such as with a counter within a loop), but you can only declare a let variable inside of its scope once. The latter is not true for var which can cause bugs.
Let me say this one more time because it was confusing to me initially: you can update a let variable, but you cannot redeclare it twice in the same scope.
Const is similar to let in that it is block-scoped. With const, the value cannot be reassigned. Unlike var and let, the use of const also requires an initializer which means it cannot be used to declare an empty variable.Â
Take a look at this:
const name = 'Player1'; let points = 50; let winner = false; if(points > 40) { Â let winner = true }
Although it looks like there is only one winner variable here, there are actually two separate winner variables because they are scoped differently, even though they have the same name. The first winner is scoped to the window but the second one is scoped to the block because it is within the âifâ loop. Logging the let variable at the end of this code would return winner as false, but changing let to var would return winner as true because the variable would not be scoped to block, meaning that the original global variable would undergo reassignment because of whatâs inside the âifâ loop.
The difference between let and const is that const makes a contract that no rebinding will happen. This means you cannot alter a const value by using an assignment operator or a unary or postfix operator (--, ++, etc) without encountering a TypeError exception. The value of const freezes the moment it is declared and cannot be reassigned.
This can also be a bit confusing though, because it is possible to change the properties of a const variable. The object itself is not immutable, but the binding is.Â
Wes Bos describes const well when he says that you can think of a const object as a person. A personâs entire identity will never change; it will remain essentially the same. Although your personality could waver, you will still always be you (unless youâre Taylor Swift I guess). Your value cannot be reassigned. However, your properties can be. Your hair color, your job, your sleep schedule, your age, etc. -- those are all subject to change. Your identity isnât. You can change properties as long as the object base remains the same. That can be illustrated with the following code:
const person = { Â name: 'Noey', Â age: 22 } person.age = 23
Thereâs no problem with this, but the entire variable value cannot be changed.Â
To sum it all up, use const when the value of a variable will not be changed. Use let if rebinding will be needed. And try to start phasing out var if you can (but remain aware of scoping differences) since thatâs generally been deemed as good practice in ES6.















