Course: Section

Get Started with Modern React: Intro, Setup, and ES6 Basics

Episode: Title

S01・V07: Variables

Date Created: July 17th, 2019
Last Updated: 27 days ago

Objectives
  1. We will look at variables declared with“var”.
  2. We will look at variables declared with “let” in ES6.
  3. We will look at constant variables declared with “const” in ES6.
Watch Video
Duration: 9m 34s

var

From the 1st Edition of JavaScript until the 6th Edition, the only way to declare a variable was with the keyword var.

For example, the variable with the name x is declared as follows:

var x;

If it is not initialized to a value, it is undefined.

var x;
console.log("x:", x); // Prints `x: undefined`

The console logs: x: undefined.

Initializing var

You can optionally initialize the variable to a value when it is declared. For example:

var y = 5;
console.log("y:", y); // Prints `y: 5`

The console prints y to its initialized value of 5.

Execution Context

The scope of a variable declared with var is its current “execution context”. The execution context is either the enclosing function, or if it is declared outside any function, it is global.

We can demonstrate this by setting up a function, with a variable, i, declared in the initialization expression of a for loop.

function test() {
  for (var i = 0; i < 3; i++) {
    console.log("i inside loop:", i); // Prints `i inside loop: 0`, `i inside loop: 1`, `i inside loop: 2`
  }
}

test();

The console prints the values 0, 1, and 2, inside the loop.

Hoisting var

We will also print the value of the variable i, before, and after, the loop.

function test() {
  console.log("i before loop:", i); // Prints `i before loop: undefined`

  for (var i = 0; i < 3; i++) {
    console.log("i inside loop:", i); // Prints `i inside loop: 0`, `i inside loop: 1`, `i inside loop: 2`
  }

  console.log("i after loop:", i); // Prints `i after loop: 3`
}

test();

Even though the variable is declared in the loop, it is evaluated before the loop, and shows the value undefined, rather than throwing an error. Any variable declared with var is processed before any code is executed, which is equivalent to declaring it at the top of its execution context. This behavior is called “hoisting”. Since we have declared i within the test function, its execution context is the function, and the variable declaration of i is hoisted to the top of the function.

This is equivalent to writing the following:

function test() {  var i;
  console.log("i before loop:", i);

  for (i = 0; i < 3; i++) {    console.log("i inside loop:", i);
  }

  console.log("i after loop:", i);
}

test();

The output is the same as before. For clarity, it is recommended to always declare var variables at the top of their scope.

Reassigning var

Variables declared with var can be reassigned.

var x = 1;
console.log("x:", x); // Prints `x: 1`

x = 2;
console.log("x:", x); // Prints `x: 2`

The variable x is assigned the value 1, and it is then reassigned the value 2.

Redeclaring var

Variables declared with var can be redeclared.

var x = 1;
console.log("x:", x); // Prints `x: 1`

var x = 2;console.log("x:", x); // Prints `x: 2`, same variable!

The variable x has the value 1, and it is then redeclared to have the value 2. Note that we are dealing with the same variable x when it is redeclared. It does not become a new variable.

function test() {
  var x = 1;
  if (true) {
    var x = 2;	// same variable!
    console.log("x:", x); // Prints `x: 2`
  }
  console.log("x:", x); // Prints `x: 2`
}

test();

The variable x was assigned the value 1 on line 2, and then reassigned to the value 2 on line 4, so it prints out with the reassigned value on line 5, and again on line 7.

let

Since JavaScript’s 6th Edition, which is also called “ES6” for short, we can also declare variables with the keyword let.

For example, the variable with the name x would be declared as follows:

let x;

If not initialized to a value, it is undefined.

let x;
console.log("x:", x); // Prints `x: undefined`

The console logs: x is undefined.

Initializing let

You can optionally initialize the variable to a value when declaring it.

For example:

let x = 7;
console.log("x:", x); // Prints `x: 7`

The console prints y to its initialized value of 7.

The scope of a variable declared with let is its enclosing block, or the expression in which it is used. Let’s use the same loop example as we did previously:

function test() {
  console.log("i before loop:", i);

  for (let i = 0; i < 3; i++) {
    console.log("i inside loop:", i);
  }

  console.log("i after loop:", i);
}

test();

We get an uncaught ReferenceError stating that i is not defined, for the log output before the loop. In other words, variables declared with let are not hoisted.

Remove the console.log() before the loop.

function test() {
  for (let i = 0; i < 3; i++) {
    console.log("i inside loop:", i);
  }

  console.log("i after loop:", i);
}

test();

We also get an uncaught ReferenceError stating that i is not defined, for the console.log("i after loop:", i). Since the variable i is declared with the keyword let, it is only defined within the for loop.

Reassigning let

Variables declared with let can be reassigned.

let x = 7;
console.log("x:", x); // Prints `x: 7`

x = 8;
console.log("x:", x); // Prints `x: 8`

The variable x is assigned the value 7, and it is then reassigned the value 8.

Variables declared with let cannot be redeclared within the same scope.

let x = 7;
console.log("x:", x);

x = 8;
console.log("x:", x);

We get an uncaught SyntaxError stating that the identifier 'x' has already been declared.

Since let variables are scoped to the block they are in, if they have different scopes, then they are different variables, even if they have the same name.

function test() {
  let x = 7;
  if (true) {
    let x = 8;	// different variable
    console.log("x:", x); // Prints `x: 8`
  }
  console.log("x:", x); // Prints `x: 7`
}

test();

The variable x is assigned the value 8 within the scope of the if block, and a different variable with the same name x is assigned the value 7 within the scope of the function.

const

Since JavaScript “ES6”, we also have the const variable declaration. These variables are called “constants”.

A “constant” cannot change through reassignment:

const x = 3;
console.log("x:", x); // Prints `x: 3`

x = 4;
console.log("x:", x); // Prints `Uncaught TypeError: Assignment to a constant variable.`

We get an uncaught TypeError when we try reassignment to a constant variable.

Constants are block-scoped, much like variables defined using the let statement.

if (true) {
  const x = 4;
  console.log("x:", x); // Prints `x: 4`
}

console.log("x:", x); // Prints `Uncaught ReferenceError: x is not defined.`

For the console.log(), outside the if statement, we get an uncaught ReferenceError, stating that x is not defined, because its scope is only within the if block.

A constant cannot be redeclared, within the same scope.

if (true) {
  const x = 4;
  console.log("x:", x);
}

console.log("x:", x);

We get an uncaught SyntaxError stating that the identifier 'x' has already been declared.

However, if the same variable name is declared within different scopes, this is not a redeclaration, since we are dealing with two separate variables:

function test() {
  const x = 7;
  if (true) {
    const x = 8;	// different variable
    console.log("x:", x); // Prints `x: 8`
  }
  console.log("x:", x); // Prints `x: 7`
}

test();

The constant x is assigned the value 8 within the scope of the if block, and a different constant with the same name x is assigned the value 7, within the scope of the function.

Block-scoping makes it easier to reason about code, so we will only use let and const variables during this video course.

Summary

We will now summarize the differences between var, let, and const:

  • var has scope of its execution context, meaning its function scope or global scope. Ignoring the global scope, we say it has “function scope”.
  • let and const, on the other hand, are scoped to the block they are in (“block-scoped”).
  • The declaration of a var variable is hoisted to the top of its function.
  • On the other hand, let and const variables are not hoisted.
  • Both var and let variables can be reassigned.
  • However, const is a constant, so it cannot be reassigned.
  • var can be redeclared.
  • But, both let and const cannot be redeclared in the same scope.

Next Up…

In the next video, we will talk about ES6 template literals.