ES6 var, let & const
With the dawn of ES6 we gained two new ways of storing data to a unique address, let & const. What do they have in common with var and where do they differ? Let's have a look.
var
First we need to understand how var works. var or variable is used to assign data to an address in memory. A variable consists of two parts: the name (or declaration) and the value.
The default value a var has right after it has been declared is undefined. This is because the keyword var gets processed before any other code. This concept is called hoisting, but more on that later.
In Javascript a var is mutable. This means you can overwrite its value at any point without having to declare a new var or having to change the name.
You can assign any data type to a var without first specifying the type. The value of a var can also be overwritten with data from a different data type. This can be seen in the following example:
The scope of a var is its current execution context. This can either be the global scope or an enclosing function scope.
hoisting
var declarations as well as function declarations are being processed before any other code. That means that wherever they are in your code, the javascript engine treats them as if they were declared at the top of their respective scopes. This proces is called hoisting. Here's an example of that:
As you can see, we are able to console.log() the variable before it is declared. This is possible because what the engine is doing is this
It pulls the var declaration to the top of the code and initialises it with the value undefined as we said earlier. After that the code proceeds as it was typed, the value of name is changed to value and when we console.log() it we find that the value has changed.
When the engine hoists vars and functions it reserves a space for them in memory. If they are declared on the global scope, the engine also adds them as properties to the global object. When Javascript is executed in the browser this global object is the window object.
Here I declared the variable name on the global scope, as you can see it is also part of the window object's properties.
If you are working on pre-ES6 Javascript projects you are only going to find var as variable storage, since it was the only way. When you are writing code in ES6 you're better off using const and let since they are more predictable and force better coding practices in a way.
A warning, find and replacing all vars with let or const might lead to unexpected errors
let
let is an ES6 way of declaring variables. The name let was most likely taken from other languages like Scheme and Basic. Variables declared with let are block scoped. Just like a var the initial value a let gets after it is declared is undefined.
Unlike var, let variables aren't hoisted by the Javascript engine, nor are they added as a property to the global object. This means they can only be called after they have been declared. Calling a let before its declaration will result in a ReferenceError. Until the line is reached where a let is declared it finds itself in a temporal deadzone.
Also unlike with var it is forbidden to declare a let with the same name twice within the same scope. Doing so anyway will result in a SyntaxError.
const
const or constant is the ES6 way of declaring an address to which data can only be assigned once. Once a const gets data assigned to it, no new data can be assigned to it at a later point in time. Trying to do so will result in a SyntaxError.
The const is quite similar to let. It also is block scoped. Its name must also be unique to its scope. And it also lives in a temporal deadzone, meaning it can only be called after has been declared.
However due to the restrictive nature of const unlike with var and let, when a const is declared it must be assigned a value immediately. Failing to do so will result in a SyntaxError.
The value of const is not completely immutable however. Properties on objects stored in a const can still be added or altered. The same thing goes for arrays.
To prevent this Object.freeze() can be used.
Best practice
As we wrap up on these different types of data addresses in Javascript we are left with the question which one to use and why. This is often debated and what you'll see used in practice will differ from project to project. In my work I try to apply the following rule:
Does this value need to change after I have set it? No? Use const. Yes? Use let.
This simple rule makes your code predictable through a concept called minimisation of mutable state. By lowering the amount of state changes in an application, the amount of possible side effects also decreases, which is a good thing.
With the properties of let and const you can cover any use case. Them being more predictable var has become obsolete. It is still valid Javascript code however.