Since ES2015, JavaScript has released two more keywords as an alternative to var
. They are let
and const
keywords. These two keywords are included in JavaScript to fix some weird behaviors of var
keyword that have been causing errors when building JavaScript applications.
To understand the differences between var
, let
, and const
, you need to learn more about var
first.
The weird behavior of var keyword
As you may know, the var
keyword is used in JavaScript to declare and initialize a variable. You declare a variable when you assign a variable name, but you don’t assign any value to it:
var declare;
Then you can initialize your variable by assigning a value to it:
declare = "Initializing variable";
You can do both at the same time too:
var declared = "Initialized";
Now here are some problems with the var
keyword.
Variable re-declaration
First, you can re-declare a variable with the same name, even though it will cause duplicates:
var declared = "Initialized";
var declared = "This is also initialized";
console.log(declared); // This is also initialized
The expected outcome of the code above is that the second line should throw an error because you can’t have two variables with the same name. But instead of throwing an error, JavaScript will simply re-assign your variable value with the second declaration’s value.
The let
keyword fixes this behavior by throwing an error when you declare a variable with a used name:
let declared = "Initialized";
let declared = "This is also initialized"; // SyntaxError: Identifier 'declared' has already been declared
Variable hoisting
Hoisting is JavaScript’s built-in behavior to secretly define all declarations at the top of the scope. This helps you to call on variables and functions before you initialize them:
myFunction();
function myFunction() {
console.log("Hello world!");
}
But while hoisting is good for functions, it’s actually bad for variables because you shouldn’t be able to call on variables before you initialize them. The following variable declaration:
console.log(x); // undefined
var x = 7;
Is actually executed like this by JavaScript:
var x;
console.log(x); // undefined
x = 7;
The let
keyword fix this behavior by throwing an error when you try to access the variable before initialization:
console.log(x); // ReferenceError: x is not defined
let x = 7;
Variable scoping
In general, variables in programming languages are expected to be scoped inside the block where it was declared and initialized. A block is simply a piece of code bounded using curly braces ({}
). You commonly create code blocks when you use if
, switch
, for
, while
, and so on.
The following is an example of an if
block:
if (true) {
// the if block here
}
And here’s a function block:
function sum() {
// function block here
}
Now here’s the problem: variables declared with var
can be accessed outside the block scope, but not outside of the function.
The code below should have caused an error:
if (true) {
var x = 7;
}
console.log(x); // 7
But var
can’t be accessed outside the function
:
function sum() {
var x = 7;
}
console.log(x); // Error: x is not defined
As you can see, the var
keyword has inconsistent scoping because it’s either global or function-scoped, when it should’ve been block scoped.
The let
keyword has fixed this behavior by throwing an error when you declare the variable inside any block, whether it’s an if
statement or a function
statement:
if (true) {
let x = 7;
}
console.log(x); // Error: x is not defined
By using let
keyword, your variable will be limited to the block it was declared and initialized.
What about const?
The const
keyword is the same as let
keyword with two extra rules:
- variables declared with
const
must be initialized / assigned a value - variables declared with
const
can’t be re-assigned another value after initialization
So you can’t declare a variable with const
like this:
const declare; // Error
You must initialize the variable immediately after declaration:
const declare = "Initialized";
And you can’t change the value after that:
const declare = "Initialized";
declare = "Change the value"; // Error
In other words, the const
keyword is used to create a variable with a constant (fixed) value. It stays the same throughout the lifetime of your JavaScript application.
Conclusion
To conclude, here are the differences between var
, let
, and const
keywords:
- The
var
keyword can be re-declared,let
andconst
won’t allow you to do it. - All three are hoisted to the top of their scope, but
var
is initialized withundefined
as value whilelet
andconst
are not initialized at all. - The
var
keyword has inconsistent scoping,let
andconst
are always block-scoped.
The var
keyword should stop being used in new projects, and you should declare a variable using let
by default. Only use const
for variables with fixed values. Ideally, you should have lots of let
keywords and fewer const
with no var
.
But you will definitely find lots of var
keywords in old projects, so you should schedule a time to refactor them into let
if you can.
Bonus weird part on JavaScript
Here’s another weird behavior of JavaScript. It allows you to initialize a variable without declaring a variable with var
keyword:
declared = "Initialized";
console.log(declared);
In other programming languages, this should lead to an error because declared
is not defined. Unfortunately, you can’t fix this problem with either let
or const
keywords. You need to use the use strict
JavaScript directive.
"use strict";
declared = "Initialized";
console.log(declared); // error here
The strict mode will turn all bad syntax of JavaScript into real errors.