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:
One of many operations a JS interpreter performs in the background
Variable/Function Declarations are hoisted to top of the Scope
= Hoisting only moves the Declaration
→ Any Assignments are left in placeMental image to help us illustrate why we can access Functions & Variables before they are defined
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
- A Declaration
- 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';
What are the impacts of Block Scope?
ES6 gives 2 new Variable Declaration keywords:
let
andconst
= Difference betweenlet
andconst
→ Variables declared with ES6 Keywords are block-scopedThey are accessible only in code block they are defined in
= A code block
→ Separated by curly bracesVariables created with
let
orconst
are not hoisted
= Their definition is not pulled to the top like Variables declared withvar
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
Hoisted completely
= Entire Function’s body is moved to the top
→ Allows you to call a Function before it has been declaredJS 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
- Function Declaration
- 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();
= This above code is interpreted by the JS Engine like this:
function showState() {
console.log(“Ready”);
}
var showState;
showState = function(){
console.log(“Idle”);
};
showState();
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;
}
}
= 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);
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;
}
};
= 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);
Top comments (0)