var, let, and const in JavaScript: a cheatsheet.

var, let, and const in JavaScript: a cheatsheet

// toc here

var

The var statement declares a variable in JavaScript which abides to the following rules:

  • is function-scoped or globally-scoped.
  • is not subject to the temporal dead zone.
  • it creates a global property on window with the same name.
  • is reassignable.
  • is redeclarable.

Function-scoped or globally-scoped

var creates a global variable when appears in the global scope. In addition, it creates a global property on window with the same name:

var city = "Florence";

console.log(window.city); // "Florence"

When declared inside a function, the variable is scoped to that function:

var city = "Florence";

function bubble() {
var city = "Siena";
console.log(city);
}

bubble(); // "Siena"

console.log(city); // "Florence"

var declarations are subject to hoisting:

function bubble() {
city = "Siena";
console.log(city);
var city; // hoists
}

bubble(); // "Siena"

Accidental global variables

Variables assigned without any statement, be it var, let, or const, become global variables by default:

function bubble() {
city = "Siena";
console.log(window.city);
}

bubble(); // "Siena"

To neutralize this behaviour we use strict mode:

"use strict";

function bubble() {
city = "Siena";
console.log(window.city);
}

bubble(); // ReferenceError: assignment to undeclared variable city

reassignable and redeclarable

Any variable declared with var can be later reassigned, or redeclared. An example of redeclaration:

function bubble() {
var city = "Florence";
var city = "Siena";
console.log(city);
}

bubble(); // "Siena"

An example of reassignation:

function bubble() {
var city = "Siena";
city = "Florence";
console.log(city);
}

bubble(); // "Florence"

let

The let statement declares a variable in JavaScript which abides to the following rules:

  • is block scoped.
  • is subject to the temporal dead zone.
  • it does not create any global property on window.
  • is reassignable.
  • is not redeclarable.

Block scoped

A variable declared with let does not create any global property on window:

let city = "Florence";

console.log(window.city); // undefined

When declared inside a function, the variable is scoped to that function:

let city = "Florence";

function bubble() {
let city = "Siena";
console.log(city);
}

bubble(); // "Siena"

console.log(city); // "Florence"

When declared inside a block, the variable is scoped to that block. An example with the block statement:

let city = "Florence";

{
let city = "Siena";
console.log(city); // "Siena";
}

console.log(city); // "Florence"

An example with an if block:

let city = "Florence";

if (true) {
let city = "Siena";
console.log(city); // "Siena";
}

console.log(city); // "Florence"

var instead, doesn't care about blocks:

var city = "Florence";

{
var city = "Siena";
console.log(city); // "Siena";
}

console.log(window.city); // "Siena"

Temporal dead zone

let declarations are subject to hoisting, but temporal dead zone kicks in:

function bubble() {
city = "Siena";
console.log(city); // TDZ
let city;
}

bubble();

// ReferenceError: can't access lexical declaration 'city' before initialization

Temporal dead zone prevents access to let declarations before their initialization. Another example:

function bubble() {
console.log(city); // TDZ
let city = "Siena";
}

bubble();

// ReferenceError: can't access lexical declaration 'city' before initialization

We can see that the exceptions are the same in both examples: the proof that temporal dead zone kicked in.

Further resources on the topic: Temporal dead zone demystified.

Reassignable, not redeclarable

Any variable declared with let can't be redeclared. An example of redeclaration which throws:

function bubble() {
let city = "Siena";
let city = "Florence";
console.log(city);
}

bubble(); // SyntaxError: redeclaration of let city

An example of valid reassignation:

function bubble() {
let city = "Siena";
city = "Florence";
console.log(city);
}

bubble(); // "Florence"

const

The const statement declares a variable in JavaScript which abides to the following rules:

  • is block scoped.
  • is subject to the temporal dead zone.
  • it does not create any global property on window.
  • is not reassignable.
  • is not redeclarable.

Block scoped

A variable declared with const does not create any global property on window:

const city = "Florence";

console.log(window.city); // undefined

When declared inside a function, the variable is scoped to that function:

const city = "Florence";

function bubble() {
const city = "Siena";
console.log(city);
}

bubble(); // "Siena"

console.log(city); // "Florence"

When declared inside a block, the variable is scoped to that block. An example with the block statement {}:

const city = "Florence";

{
const city = "Siena";
console.log(city); // "Siena";
}

console.log(city); // "Florence"

An example with an if block:

const city = "Florence";

if (true) {
const city = "Siena";
console.log(city); // "Siena";
}

console.log(city); // "Florence"

Temporal dead zone

const declarations are subject to hoisting, but temporal dead zone kicks in:

function bubble() {
console.log(city);
const city = "Siena";
}

bubble();

// ReferenceError: can't access lexical declaration 'city' before initialization

Not reassignable, not redeclarable

Any variable declared with const can't be redeclared, nor reassigned. An example of redeclaration which throws:

function bubble() {
const city = "Siena";
const city = "Florence";
console.log(city);
}

bubble(); // SyntaxError: redeclaration of const city

An example of reassignation which trows as well:

function bubble() {
const city = "Siena";
city = "Florence";
console.log(city);
}

bubble(); // TypeError: invalid assignment to const 'city'
Valentino Gagliardi

Hi! I'm Valentino! I'm a freelance consultant with a wealth of experience in the IT industry. I spent the last years as a frontend consultant, providing advice and help, coaching and training on JavaScript, testing, and software development. Let's get in touch!