DEV Community

Cover image for Hoisting - JavaScript Core Concepts
Angeline Wang
Angeline Wang

Posted on

Hoisting - JavaScript Core Concepts

The Section 2: Functions & Methods of my JavaScript Core Concepts Series is divided into 6 Parts:

Part 1 Functions
Part 2 Classes
Part 3 Methods
Part 4 Callback Functions
Part 5 Scope
Part 6 Hoisting

Hoisting: Variables vs Functions & Classes

Part 1 What is Hoisting?

= Here are a few different definitions of Hoisting:

  1. One of many operations a JS interpreter performs in the background

  2. Variable/Function Declarations are hoisted to top of the Scope
    = Hoisting only moves the Declaration
    → Any Assignments are left in place

  3. Mental image to help us illustrate why we can access Functions & Variables before they are defined

  4. Picture how code is reorganized before Execution

During Execution

= When Engine is actually executing our code
→ Our Function & Variable Declarations: No longer there at all
→ They have already been declared in a previous run

Impact of Hoisting

= Hoisting Functions & Variables is reason why we can use some of them before they are actually declared
→ Function & Variable Declarations are pulled to top of their scope
Try to access them: They’ve already been declared

Part 2 Hoisting Variables

JS Variables’ Behaviour

= 2 Parts

  1. A Declaration
  2. An Initialisation/Assignment

= Even when you declare and assign a Variable in one line like this: var name = 'Angeline'
→ The JS engine still treats this line of code as 2 separate statements
→ It treats it as if you wrote this:

var name;
name = 'Angeline';
Enter fullscreen mode Exit fullscreen mode

What are the impacts of Block Scope?

  1. ES6 gives 2 new Variable Declaration keywords: let and const
    = Difference between let and const
    → Variables declared with ES6 Keywords are block-scoped

  2. They are accessible only in code block they are defined in
    = A code block
    → Separated by curly braces

  3. Variables created with let or const are not hoisted
    = Their definition is not pulled to the top like Variables declared with var

var Variable Declarations

= var Variable Declarations are hoisted AND fully initialized
→ With a Value Assignment of undefined by default

Variable Declared w/in a Scope

= Belongs to that Scope

Regardless of Location of Variable Declaration w/in a Scope

= All Variable Declarations are moved to top of their Scope (Global or Local)
→ This is called Hoisting

let Variables Declarations

= let Variable Declarations cannot be read/written until they are fully initialized
→ When are they fully initialized? Where they are actually declared in the code
let Variable Declaration is hoisted, but not initialized with undefined value (which is done by default with var variables)
let Declarations are not hoisted like var Declarations

const Variable Declarations

= Same behaviour as let variables

Hoisting In Action

= Variable/Function is not physically moved
→ Hosting is just a model describing what the JS engine does behind the scenes

What is Hoisted?

= (var) Variable & Function Declarations are hoisted
→ But Variable & Function Assignments are left in their place
Even if the Declaration and Assignment happen in the same line of code as in: var name = 'Angeline'

Reference before Declaration

= If you reference a Variable/Function before its Declaration
→ Expect a ReferenceError to be thrown

Referenced before Assignment

= Except a Default Value of undefined to be the Output
→ If var is used

Temporal Dead Zone

= Section from beginning of Block to actual Variable Declaration

Purpose

= Mechanism that ensures better coding practice
→ Forces you to declare a Variable before you use it

Compilation

Definition

= Internals of JS & how it actually works
→ V8 Engine increases performance by compiling JS to machine code before executing it

Application

= Engine makes multiple runs through our code
→ 1 of the early runs: It will declare all Functions & Variables
→ So when the code is executed: They will already be defined

Reference Error Prevention

= Make sure you are using only let and const for Variable Declaration

Part 3 Hoisting Functions

= Hoisting also affects Function Declarations

Function vs Variable Hoisting

= Only Declaration of the Variable is pulled to the top
→ Value Assignment: Stays where it is
→ Cannot access Value of a Variable the same way we can call Functions

Function Declaration vs Expression

= Difference: Check position of word function in the statement
→ If function is very 1st thing in the statement: It is a Function Declaration
→ Not function is not the first thing: It is a Function Expression

Hoisting of Declarations vs Expressions

Declarations

  1. Hoisted completely
    = Entire Function’s body is moved to the top
    → Allows you to call a Function before it has been declared

  2. JS Engine
    = Moves Declaration & its contents
    → To beginning of the Scope

Expressions

= Are not hoisted
→ When a Function is assigned to a Variable
Rules are the same as Variable Hoisting

= Only the Declaration is moved
→ While the Assignment is left in place

Caution w/ Function Expressions

= Variable Declaration will be hoisted
→ But Function assigned to Value not hoisted
→ Function will not be Hoisted

= Cannot be used before it is read
→ Actual Assignment of the Function as a Value stays where it is
→ So if we try to call the Function, we will get an Error

Part 5 Hoisting Priority

  1. Function Declaration
  2. Variable Declaration = Assignments: Variable or Function, are not hoisted, so are read later, and will overwrite Function and Variable Declaration Values

Create Function w/ Variable Assignment 1st

= Will still be read after Function Declaration

Code Example

var showState = function() {
    console.log(“Idle”);
};

function showState() {
    console.log(“Ready”);
}

showState();
Enter fullscreen mode Exit fullscreen mode

= This above code is interpreted by the JS Engine like this:

function showState() {
    console.log(“Ready”);
}

var showState;

showState = function(){
    console.log(“Idle”);
};

showState();
Enter fullscreen mode Exit fullscreen mode

Arrow Functions

= Interpreted the same way Function Expressions are in terms of hosting?

Part 4 Hoisting Classes

= Class Declarations
→ Hoisted similarly as Variables declared with let statement

Code Example

var user = new Person(‘Angeline’, 20);

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
}
Enter fullscreen mode Exit fullscreen mode

= Person Class being used before Declaration
→ Produces a Reference Error: Similar to that in let Variables

Solution

= Must use the Person Class after the Declaration like this:

class Person {
    constructor(name, age) {#
        this.name = name;
        this.age = age;
    }
}

var user = new Person(‘Angeline’, 20);
console.log(user);
Enter fullscreen mode Exit fullscreen mode

Alternative Way to Create Classes

= Using a Class Expression
→ Using var, let, or const Variable Declaration Statements

Code Example

console.log(typeof Person);

var user = new Person(‘Angeline’, 20);

var Person = class {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
};
Enter fullscreen mode Exit fullscreen mode

= Person Class is hoisted as a Function Expression
→ But it cannot be used because its value is undefined

Solution

= Use Person Class after Declaration:

console.log(typeof Person);

var Person = class {
    constructor(name. age) {
        this.name = name;
        this.age = age;
    }
};

var user = new Person(‘Angeline’, 20);
console.log(user);
Enter fullscreen mode Exit fullscreen mode

Top comments (0)