JavaScript's Statements and Why You Shouldn't Use var

Blog

In 2015, JavaScript received two new ways to declare a variable, thanks to ECMAScript 6. Before that, one could only use the var statement or omit it. Now we have two new cool kids on the playground: let and const. Before going off on var, let us understand what the other two do.

If you already know about let and const and only want to read about (my opinion on) var, you can skip ahead.

let

Declaring with the let statement means that the value of a variable can and will change. You don't have to initialize it when declaring. Variables declared this way are always block-scoped. To understand the block in block-scoped, we can quote the MDN Web Docs:

The block is delimited by a pair of braces ("curly brackets") and contains a list of zero or more statements and declarations.

So variables declared with let only exist between a pair of braces. Outside of them, they aren’t accessible. The top level of a program is also a block in some way. All variables declared there are accessible everywhere. Redeclaring a variable in a nested block creates a new variable. The original's value isn't affected by this.

For a better understanding, let’s take a boolean value as an example that tracks the status of a checkbox.

let checked = false;

When the user checks the checkbox, we want the variable's value to become true. And with each consecutive check, the variable's value should reflect it.

const checkbox = document.getElementsByTagName("input")[0];
let checked = false;

if (checkbox) {
    checkbox.addEventListener("change", () => {
        checked = !checked; // true or false
    });
}

const

After using const to declare a variable, its value can’t change through reassignment. Variables declared this way are block-scoped as well. The value can be mutable or not, depending on the variable type.

We can divide the possible types of variables into two groups. The first group contains simple types, like numbers, strings, and booleans. These can only be one value. With these, a variable's value can't change if declared with the const statement.

const active = false;
const birthYear = 1986;
const name = "Jim";

active = true; //  Uncaught TypeError: invalid assignment to const 'bool'
birthYear = 1989; //  Uncaught TypeError: invalid assignment to const 'age'
name = "Jenny"; //  Uncaught TypeError: invalid assignment to const 'name'

The second group contains types with many possible values, like arrays and objects. You can’t reassign a different value to an, with const declared, array. The same is true for objects. But the properties are mutable, even if the variable is a constant.

const primes = [2, 3, 5, 7, 11];
const person = { name: "Hanna", lastName: "Smith" };

primes.push(13)
console.log(primes) // [2, 3, 5, 7, 11, 13]

person.lastName = "Frank"
console.log(person); // Object { name: "Hanna", lastName: "Frank" }

primes = [1, 2, 3]; // Uncaught TypeError: invalid assignment to const 'primes'
person = { name "Susan", lastName: "Schwartz"} //  Uncaught TypeError: invalid assignment to const 'person'

This distinction is important to remember. Only because a variable is a constant doesn't always mean it will keep the same value.

var

With the var statement, you can declare a function-scoped or globally-scoped variable. Like with the let statement, you don't have to initialize it.

When using var to declare variables, they get created before any code gets executed. This results in non-existing variables not throwing ReferenceErrors when used. Instead, they show up as undefined.

console.log(x); // undefined
console.log(y); // Uncaught ReferenceError: y is not defined
var x = true;
console.log(x); // true

What is so bad about this behavior? If I make a mistake and use a non-existing variable, I should get the appropriate error message.

That is not the only problem with var. Like with let, it is possible to redeclare a variable in a nested scope. The problem here is that it also mutates the value of the already declared variable. It is a great way to shoot yourself in the foot and never the behavior you want. Or at least you shouldn’t want.

See the behavior compared to let below.

var x = 1;
let y = 2;

if (x === 1) {
    var x = 2;
    let y = 1;

    console.log(x); // 2
    console.log(y): // 1
}

console.log(x); // 2
console.log(y): // 2

Almost the same as let, right? Almost. In this example, it is easy to see that there already is a variable with the same name. And if you know what var does, you’ll know what will happen to the first variable. Now imagine you are working in a team. Many people are working on the same code. And then, someone adds some code, redeclaring a variable and breaking the program.

Before ES6, var was the only statement in JS. With the addition of let and const, there was no more reason to use it. If you find yourself on StackOverflow, you might encounter code with var statements. The code might still work, but at least replace var with let and const if you decide to use the code.

Using let and const to declare a variable also improves the readability of your code. These two already imply how the variable will behave. With var, it's all up to the imagination.

The only excuse for using var is if you have to support browsers that do not support ES6. For everything else, use let and const. Thank you.