In JavaScript variables are declared with let and const. That’s been the case since ECMAScript 6 (2015). Nowadays, you should only use these in your code.
But if you’ve been in the programming world for a while, or if you look at outdated tutorials (really not very updated) you will find the var syntax.
So it’s about time we stop ignoring the blue elephant in the room 🐘, and talk a bit about the old var syntax.
And frankly it’s an interesting topic (and even fun), if you feel like seeing how sometimes things don’t turn out quite right, and how hard it is to fix them.
Variable Declaration with var
The var keyword is the original syntax for declaring variables in JavaScript since the first version ECMAScript 1.
var age = 25;
console.log(age); // 25
In this example, age is declared with var and assigned the value 25.
Before ES6, var was the only way to declare variables in JavaScript. At first glance, it seems like a “pretty normal” syntax 🤷.
However, the behavior of var variables had certain “peculiarities”, which were unintuitive for programmers.
In short, the use of variables with var, instead of working like most languages did, did it “its own way”.

Allow me to add a bit of humor to the matter 😊.
Characteristics of var
Let’s see what these “peculiarities” were 👇
First, variables defined with var have function scope. This means a variable declared with var is accessible throughout the function in which it is declared.
function myFunction() {
if (true) {
var message = "Hello World";
}
console.log(message); // message is accessible here ⚠️
}
myFunction();
In this example,
- The variable
messageis accessible outside theifblock 😮 - This is because
varhas function scope, meaning it exists in the entireexamplefunction.
This is very different from other languages, where scope is generally block-level (what’s between {}).
Another peculiarity of var is its behavior with Hoisting. This means variable declarations are hoisted to the top of their scope, but initializations are not hoisted.
As a result, variables declared with var are accessible before their declaration, but their value will be undefined until the line where they are initialized is reached.
// we access the variable before declaring it ⚠️
console.log(name); // undefined
var name = "Luis";
console.log(name); // "Luis"
In this example,
- The declaration of the variable
nameis hoisted to the beginning of the execution context - So we can use the variable before declaring it 😮
- It will give a value of
undefinedin the first call toconsole.log.
Finally, variables declared with var could be redeclared within the same scope, without any error occurring.
var number = 5;
var number = 10; // I redeclare it
console.log(number); // 10
Here, the second declaration of number overwrites the first one 😮
The three things independently were quite bad. But combined they were terrible (a real, hyper-dangerous mess of variables) 🤦.
The New let and const
The peculiarities of var are understandable in the way JavaScript emerged (resources of machines at the time, ease of use, etc). Frankly, it wasn’t expected to have as much impact as it does today.
But, as the language became more important, these peculiarities made development very difficult. Especially in medium and large projects.
So, in the great normalization that ES6 represented, they took the opportunity to change the way of working with variables (they became more similar to what is found in other languages).
Thus let and const (which we already know) emerged, and they came precisely to fix these behaviors that var had.
| Feature | let/const | var |
|---|---|---|
| Scope | Block | Function |
| Hoisting | No | Yes |
| Multiple Declaration | No | Yes |
They have block scope, meaning a variable declared with let or const is only available within the block in which it is declared, like in an if or a for.
function myFunction() {
if (true) {
let message = "Hello World";
}
console.log(message); // ❌ ReferenceError: message is not defined
}
myFunction();
They also have hoisting, but they are not initialized. Furthermore, the concept of Temporal Dead Zone (TDZ) is introduced.
// we access the variable before declaring it
console.log(name); // ❌ ReferenceError: name is not defined
let name = "Luis";
console.log(name); // "Luis"
That is, if we try to access a variable declared with let or const before its declaration, it results in a ReferenceError
They do not allow redeclaring the same variable in the same scope. Attempting to do so results in a SyntaxError.
let number = 5;
let number = 10; // ❌ SyntaxError: Identifier 'number' has already been declared
In Summary
For many, the behavior of var was a mistake in JavaScript’s design, a legacy we carry from its beginnings.
In fact, part of the “hate” that JavaScript sometimes gets is because of things like the behavior of var (and because they haven’t realized things have changed).
We also have to consider the resources machines had at the time (1995), compared to what we have today. As well as the improvements in modern interpreters.
Today, variable declaration with var is still functional. It cannot be removed due to backward compatibility reasons with existing code.
I like it as a story to illustrate how, sometimes, some decisions are very hard to undo (because you have millions of lines of code running)
However, nowadays the use of var is completely discouraged. Instead, always use the syntax defined in ES6 with let and const.
