DEV Community

Valentino Gagliardi
Valentino Gagliardi

Posted on • Originally published at valentinog.com

var, let, and const in JavaScript: a cheatsheet

var, let, and const in JavaScript: a cheatsheet

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

var declarations are subject to hoisting:

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

bubble(); // "Siena"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

An example of reassignation:

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

bubble(); // "Florence"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

An example with an if block:

let city = "Florence";

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

console.log(city); // "Florence"
Enter fullscreen mode Exit fullscreen mode

var instead, doesn't care about blocks:

var city = "Florence";

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

console.log(window.city); // "Siena"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

An example of valid reassignation:

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

bubble(); // "Florence"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

An example with an if block:

const city = "Florence";

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

console.log(city); // "Florence"
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
qq449245884 profile image
qq449245884

Hello, may I translate your article into Chinese?I would like to share it with more developers in China. I will give the original author and original source.

Collapse
 
amt8u profile image
amt8u

Covered most of the scenarios and the top diagram would be quite effective to start. But I can say from my experience, Its really tricky to understand TDZ.