Variables in JavaScript

In JavaScript, variables can hold different types of data. They act as containers for storing values. There are three keywords used to declare variables: var which is available in all versions of JavaScript, and const and let which were introduced later.



var

To define a variable, use the var keyword followed by the variable name, like this:

var message;

This code defines a variable named message that can be used to hold any value. (Without initialization, it holds the special value undefined.)

JavaScript implements variable initialization, so it’s possible to define the variable and set its value at the same time:

var message = "Hello World";

In JavaScript, it is perfectly legal (but not recommended) to initialize a variable with a string value and then change it to a numeric value:

var message = "Hello World";
message = 100; // legal, but not recommended


var Scope

Defining a variable inside of a function using var means that the variable is destroyed as soon as the function exits (local variable), as shown here:

function test() {
    var message = "hi"; // local variable
}
test();
console.log(message); // error!

It is, however, possible to define a variable globally by simply omitting the var operator as follows:

function test() {
    message = "hi"; // global variable
}
test();
console.log(message); // "hi"

By removing the var operator from the example, the message variable becomes global. As soon as the function test() is called, the variable is defined and becomes accessible outside of the function once it has been executed.

Although it’s possible to define global variables by omitting the var operator, this approach is not recommended.

If you need to define more than one variable, you can do it using a single statement, separating each variable (and optional initialization) with a comma like this:

var message = "hi",
    found = false,
    age = 29;


var Hoisting

When using var, the following is possible because variables declared using that keyword are hoisted to the top of the function scope:

function hoisting() {
    console.log(num);
    var num = 26;
}
hoisting(); // undefined

This does not throw an error because JavaScript technically treats it like this:

function hoisting() {
    var num;
    console.log(num);
    num = 26;
}
hoisting(); // undefined

This is “hoisting”, where the interpreter pulls all variable declarations to the top of its scope.



let

let operates in nearly the same way as var, but with some important differences. Most notable is that let is block scoped, but var is function scoped.

if (true) {
    var name = 'Matt';
    console.log(name); // Matt          
}
console.log(name); // Matt

if (true) {
    let age = 26;
    console.log(age); // 26
}
console.log(age); // ReferenceError: age is not defined

Here, the age variable cannot be referenced outside the if block because its scope does not extend outside the block. Block scope is strictly a subset of function scope, so any scope limitations that apply to var declarations will also apply to let declarations.



Temporal Dead Zone

Another important behavior of let distinguishing it from var is that let declarations cannot be used in a way that assumes hoisting:

// name is hoisted
console.log(name); // undefined
var name = 'Matt';

// age is not hoisted
console.log(age); // ReferenceError: age is not defined
let age = 26;

Variables declared with let cannot be accessed or referenced before they are actually declared in the code. The period of code execution before the declaration of let variables is known as the "temporal dead zone", during which any attempts to access or reference these variables will result in a ReferenceError.



Global Declarations

Unlike the var keyword, when declaring variables using let in the global context, variables will not attach to the window object as they do with var:

var name = 'Matt';
console.log(window.name); // 'Matt'

let age = 26;
console.log(window.age); // undefined

However, let declarations will still occur inside the global block scope, which will persist for the lifetime of the page.



const

const behaves identically to that of let but with one important difference — it must be initialized with a value, and that value cannot be redefined after declaration. Attempting to modify a const variable will result in a runtime error.

const num = 16;
num = 33; // TypeError: assignment to a constant

If a const variable references an object, it does not violate the const constraints to modify properties inside that object.

const person = {};
person.name = 'Eve'; // ok



Best Practices



Don’t Use var

By using let and const, developers often find that they don't need to use var anymore in their code. This change leads to better code quality as it encourages proper variable scoping, localized declarations, and adherence to constants.



Prefer const Over let

By using const declarations, the browser and code analysis tools can ensure that variables remain constant and prevent illegal reassignments. Because of this, many developers prefer to declare variables as const by default, unless they specifically need to change their values. This approach allows developers to have a clear understanding of values that should never change and helps identify unexpected behavior when attempting to modify them.