
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
constmust be initialized / assigned a value - variables declared with
constcan’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
varkeyword can be re-declared,letandconstwon’t allow you to do it. - All three are hoisted to the top of their scope, but
varis initialized withundefinedas value whileletandconstare not initialized at all. - The
varkeyword has inconsistent scoping,letandconstare 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.