Defining variables in JavaScript

There are three ways of declaring variables in JavaScript — var, let and const. Each method of declaration functions slightly differently. Var is the original JS variable declaration method. With the advent of ES2015 let and const were added.

Variables declared with var and left uninitialized are hoisted to the top of the execution context as ‘undefined’ whereas a variable declared with let or const needs to be initialized at declaration time, before being referenced. In general it’s good practice to initialize your variables when declaring and before referencing them anyway. Let and const add some extra safeguards.

console.log(x); //undefined
var x = 'pig';
console.log(x); //pig
console.log(x); // Error! Uncaught ReferenceError: Cannot access 'x' before initialization
var x = 'pig';
console.log(x); //pig

Within the local scope (where a variable can be accessed), a var variable can be redeclared. Let and const declared variables will throw an error if you try to re-declare within this local scope.

var x = 'dog';
var x = 'cat';
console.log(x) // 'cat'
let y = 'dog';
let y = 'cat'; //Error - Uncaught SyntaxError: Identifier 'y' has already been declared

The biggest difference between var and let and const is that the var variables are ‘function scoped’. This means that their scope is defined by whether or not they live inside a function. Const and let are block scoped (anything in between curly braces, like conditionals). This makes using let and const a better option as you are less likely to accidentally re-initialize a variable in a child scope. The code below works because the if statement {} creates a new block scope for the new x variable to live. Back in the global scope, x is still the original value ‘cat’.

let x = 'cat';
let age = 5;
if (age === 5){
let x = 'dog';
console.log(x, 'food'); // dog food
}
console.log(x) //cat

If we try the same code, but declaring x using var, the global value is changed inside of the if block. This can lead to unexpected results if you’re not careful.

var x = 'cat';
let age = 5;
if (age === 5){
var x = 'dog';
console.log(x, 'food'); // dog food
}
console.log(x) //dog

Similarly, if. we don’t re-declare x in the if statement, the value is reassigned using either var or let.

let x = 'cat';
let age = 5;
if (age === 5){
x = 'dog';
console.log(x, 'food'); // dog food
}
console.log(x) //dog

This is where const comes in handy! A variable declared with const is, like the name suggests, a constant, meaning that it cannot be reassigned after initialization.

const x = 'cat';
let age = 5;
if (age === 5){
x = 'dog'; //Error! Uncaught TypeError: Assignment to constant variable.
}

This makes const a great choice when setting variables that won’t be changing. However, if a variable declared with const references an object (including arrays), the values of the properties of the object can be reassigned.

const x = ['cat', 'dog', 'chicken'];
x[2] = 'turkey';
console.log(x[2]) /// turkey

In this case the third element of the constant x is reassigned, because const only applies to the container.

In general, although it’s still common to use var in legacy code, it’s best to use let and const because of the builtin safeguards they provide. Finally, avoid declaring variables without any keyword. Variables without key words are declared globally and will overwrite any other variables with the same name.