Differences between var, let and const in JavaScript
When declaring variables, it's common to use var
since it's the normally known method. However, since ECMAScript 6, two new keywords were introduced in JavaScript to declare variables, which are let
and const
. To understand the need for these, let's first look at some points about how var
works.
Variables declared with var
are added to the beginning of the code at runtime, so they are global variables.
For example, we have this function with a variable declared inside:
function myFunction(number, compare) {
var status;
if (number < compare) {
status = 'The number is less';
} else if (number > compare) {
status = 'The number is greater';
} else {
status = 'The number is equal';
}
return status;
}
myFunction(1, 2); // The number is less
What actually happens is the following:
var status; // 'status' is globalized
function myFunction(number, compare) {
if (number < compare) {
status = 'The number is less';
} else if (number > compare) {
status = 'The number is greater';
} else {
status = 'The number is equal';
}
return status;
}
myFunction(1, 2); // The number is less
// so if we used the status variable outside the function, it would exist, just undefined
console.log(status); // undefined
Even this would work without problems (although it's bad practice):
function myFunction(number, compare) {
if (number < compare) {
status = 'The number is less';
} else if (number > compare) {
status = 'The number is greater';
} else {
status = 'The number is equal';
}
var status; // don't do this
return status;
}
myFunction(1, 2); // The number is less
This behavior is called hoisting, and it happens whether we want it to or not.
However, let
and const
don't work that way. Unlike var
, these do work at the code block level and are not transformed into global variables at runtime. This allows us to have more control over how and where we declare variables and in what places they can be manipulated.
The const
keyword, as its name says, differs from let
in that its values cannot be modified once initialized, so it must be initialized with a value. This is good because we'll never have undefined constant variables.
Using the same example with let
:
function myFunction(number, compare) {
let status;
if (number < compare) {
status = 'The number is less';
} else if (number > compare) {
status = 'The number is greater';
} else {
status = 'The number is equal';
}
return status;
}
myFunction(1, 2); // The number is less
// in this case the status variable does not exist outside the 'myFunction' function
// so it would throw an error
console.log(status); // ReferenceError: status is not defined
Now the same example with const
:
function myFunction(number, compare) {
const status
if (number < compare) {
status = 'The number is less' // TypeError: Assignment to constant variable.
} else if (number > compare) {
status = 'The number is greater' // TypeError: Assignment to constant variable.
} else {
status = 'The number is equal' // TypeError: Assignment to constant variable.
}
return status
}
myFunction(1, 2) // TypeError: Assignment to constant variable.
Although const
gives us the ability to declare constants, one point to note is that when the value of the constant is a reference, that is, an object
, another object cannot be reassigned to the constant but the one it already has can be modified. This is because the reference to the object is maintained, even though its properties are modified.
Example:
// valid
const person = {
name: '',
surname: '',
age: '',
};
const car = {
wheels: '',
color: '',
doors: '',
};
// does not throw error, because the reference to 'person' is not being modified
person.name = 'Carlos';
// TypeError: Assignment to constant variable
// Error, because it is trying to change the reference of the object 'person' to that of the object 'car'
person = car;
For these reasons it is highly recommended to use let
instead of var
. Also when declaring constants, use const
. This way we avoid bad practices and gain more control over how our application works.