Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 2126

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 61k
Author
Asked: November 26, 20242024-11-26T02:32:07+00:00 2024-11-26T02:32:07+00:00

Understanding Hoisting in JavaScript

  • 61k

What is Hoisting

Hoisting is a JavaScript mechanism where variables and function declarations are moved to the top of their scope before code execution.
this means that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.

Features of Hoisting:

  • In JavaScript, Hoisting is the default behavior of moving all the declarations at the top of the scope before code execution. Basically, it gives us an advantage that no matter where functions and variables are declared, they are moved to the top of their scope regardless of whether their scope is global or local.
  • It allows us to call functions before even writing them in our code.

Note: JavaScript only hoists declarations, not initializations.

JavaScript allocates memory for all variables and functions defined in the program before execution.

Example 1

x = 5; // Assign 5 to x  elem = document.getElementById("demo"); // Find an element elem.innerHTML = x;                     // Display x in the element  var x; // Declare x 
Enter fullscreen mode Exit fullscreen mode

Example 2

var x; // Declare x x = 5; // Assign 5 to x  elem = document.getElementById("demo"); // Find an element elem.innerHTML = x;      
Enter fullscreen mode Exit fullscreen mode

undefined vs ReferenceError

Before we begin in earnest, let’s deliberate on a few things.

console.log(typeof variable); // Output: undefined 
Enter fullscreen mode Exit fullscreen mode

In JavaScript, an undeclared variable is assigned the value undefined at execution and is also of type undefined.

console.log(variable); // Output: ReferenceError: variable is not defined 
Enter fullscreen mode Exit fullscreen mode

In JavaScript, a ReferenceError is thrown when trying to access a previously undeclared variable.

Hoisting variables

The following is the JavaScript lifecycle and indicative of the sequence in which variable declaration and initialization occurs.

Image description

However, since JavaScript allows us to both declare and initialize our variables simultaneously, this is the most used pattern:

var a = 100; 
Enter fullscreen mode Exit fullscreen mode

It is however important to remember that in the background, JavaScript is religiously declaring then initializing our variables.

As we mentioned before, all variable and function declarations are hoisted to the top of their scope. I should also add that variable declarations are processed before any code is executed.

However, in contrast, undeclared variables do not exist until code assigning them is executed. Therefore, assigning a value to an undeclared variable implicitly creates it as a global variable when the assignment is executed. This means that, all undeclared variables are global variables.

To demonstrate this behavior, have a look at the following:

function hoist() {   a = 20;   var b = 100; }  hoist();  console.log(a);  /*  Accessible as a global variable outside hoist() function Output: 20 */  console.log(b);  /* Since it was declared, it is confined to the hoist() function scope. We can't print it out outside the confines of the hoist() function. Output: ReferenceError: b is not defined */ 
Enter fullscreen mode Exit fullscreen mode

it is recommended to always declare variables regardless of whether they are in a function or global scope. This clearly delineates how the interpreter should handle them at run time.

ES5

1. var

The scope of a variable declared with the keyword var is its current execution context. This is either the enclosing function or for variables declared outside any function, global. Let’s look at a few examples to identify what this means:

  • global variables
console.log(hoist); // Output: undefined  var hoist = 'The variable has been hoisted.'; 
Enter fullscreen mode Exit fullscreen mode

We expected the result of the log to be: ReferenceError: hoist is not defined, but instead, its output is undefined.

 **Why has this happened?** 
Enter fullscreen mode Exit fullscreen mode

This discovery brings us closer to wrangling our prey.

JavaScript has hoisted the variable declaration. This is what the code above looks like to the interpreter:

var hoist;  console.log(hoist); // Output: undefined hoist = 'The variable has been hoisted.'; 
Enter fullscreen mode Exit fullscreen mode

Because of this, we can use variables before we declare them. However, we have to be careful because the hoisted variable is initialised with a value of undefined. The best option would be to declare and initialise our variable before use.

  • Function scoped variables

As we’ve seen above, variables within a global scope are hoisted to the top of the scope. Next, let’s look at how function scoped variables are hoisted.

function hoist() {   console.log(message);   var message='Hoisting is all the rage!' }  hoist(); 
Enter fullscreen mode Exit fullscreen mode

Take an educated guess as to what our output might be.

If you guessed, undefined you’re right. If you didn’t, worry not, we’ll soon get to the bottom of this.

This is how the interpreter views the above code:

function hoist() {   var message;   console.log(message);   message='Hoisting is all the rage!' }  hoist(); // Ouput: undefined 
Enter fullscreen mode Exit fullscreen mode

The variable declaration, var message whose scope is the function hoist(), is hoisted to the top of the function.

NOTE
To avoid this pitfall, we would make sure to declare and initialize the variable before we use it:

function hoist() {   var message='Hoisting is all the rage!'   return (message); }  hoist(); // Ouput: Hoisting is all the rage! 
Enter fullscreen mode Exit fullscreen mode

2. Strict Mode

In JavaScript, “use strict” is a directive that indicates that the code should be executed in “strict mode” . It was introduced in ECMAScript version 5 and is not a statement, but a literal expression . When strict mode is enabled, the JavaScript engine enforces a stricter set of rules and produces more helpful error messages, making it easier to catch common coding mistakes and avoid certain types of bugs.

Benefits of Strict Mode

Enabling strict mode in JavaScript provides several benefits, including:

Error Prevention: Strict mode helps catch errors and prevent common coding mistakes. It disallows certain actions and throws more exceptions, making it easier to identify and fix issues.
Improved Code Quality: By enforcing stricter rules, strict mode encourages developers to write cleaner and more reliable code.
Maintainability: Strict mode helps improve code maintainability by making it easier to understand and reason about the codebase.
Compatibility: Strict mode is supported by all modern browsers, except Internet Explorer 9 and lower.

'use strict';  // OR "use strict"; ---------------------------------------------------------- 'use strict';  console.log(hoist); // Output: ReferenceError: hoist is not defined hoist = 'Hoisted'; 
Enter fullscreen mode Exit fullscreen mode

ES6

ECMAScript 2015 also known as ES6 is the latest version of the ECMAScript standard, as the writing of this article, Jan 2017 and introduces a few changes to es5.

How ES6 affect the declaration and initialization of JavaScript variables?

1. let

the **let **keyword introduces block scope. Before the introduction of let in ECMAScript 6 (ES6), JavaScript had global scope and function scope.

the **let **keyword introduces block scope, not functional scope

console.log(hoist); // Output: ReferenceError: hoist is not defined ... let hoist = 'The variable has been hoisted.'; 
Enter fullscreen mode Exit fullscreen mode

Like before, for the var keyword, we expect the output of the log to be undefined. However, since the es6 let doesn’t take kindly on us using undeclared variables.

This ensures that we always declare our variables first.

However, we still have to be careful here. An implementation like the following will result in an output of undefined instead of a Reference error.

let hoist;  console.log(hoist); // Output: undefined hoist = 'Hoisted' 
Enter fullscreen mode Exit fullscreen mode

function foo() {   if (true) {     let x = 10; // block scope     console.log(x); // 10   }   console.log(x); // ReferenceError: x is not defined }  foo();  
Enter fullscreen mode Exit fullscreen mode

2. const

The const keyword was introduced in es6 to allow immutable variables. That is, variables whose value cannot be modified once assigned.

With const, just as with let, the variable is hoisted to the top of the block.

Let’s see what happens if we try to reassign the value attached to a const variable.

const PI = 3.142;  PI = 22/7; // Let's reassign the value of PI  console.log(PI); // Output: TypeError: Assignment to constant variable.  ------------------------------------------------------------ console.log(hoist); // Output: ReferenceError: hoist is not defined const hoist = 'The variable has been hoisted.'; 
Enter fullscreen mode Exit fullscreen mode

Much like the let keyword, instead of silently exiting with an undefined, the interpreter saves us by explicitly throwing a Reference error.

The same occurs when using const within functions.

function getCircumference(radius) {   console.log(circumference)   circumference = PI*radius*2;   const PI = 22/7; }  getCircumference(2) // ReferenceError: circumference is not defined 
Enter fullscreen mode Exit fullscreen mode

Our linter is also quick to inform us of this felony:

const PI; console.log(PI); // Ouput: SyntaxError: Missing initializer in const declaration PI=3.142; 
Enter fullscreen mode Exit fullscreen mode

Therefore, a constant variable must be both declared and initialized before use.

As a prologue to this section, it’s important to note that indeed, JavaScript hoists variables declared with es6 let and const. The difference in this case is how it initializes them. Variables declared with let and const remain uninitialized at the beginning of execution while variables declared with var are initialized with a value of undefined.

Hoisting functions

JavaScript functions can be loosely classified as the following:

  1. Function declarations
  2. Function expressions

1. Function declarations

These are of the following form and are hoisted completely to the top. Now, we can understand why JavaScript enable us to invoke a function seemingly before declaring it.

hoisted(); // Output: "This function has been hoisted."  function hoisted() {   console.log('This function has been hoisted.'); }; 
Enter fullscreen mode Exit fullscreen mode

2. Function expressions
Function expressions, however are not hoisted.

expression(); //Output: "TypeError: expression is not a function  var expression = function() {   console.log('Will this work?'); }; 
Enter fullscreen mode Exit fullscreen mode

Let’s try the combination of a function declaration and expression.

expression(); // Ouput: TypeError: expression is not a function  var expression = function hoisting() {   console.log('Will this work?'); }; 
Enter fullscreen mode Exit fullscreen mode

As we can see above, the variable declaration var expression is hoisted but it’s assignment to a function is not. Therefore, the interpreter throws a TypeError since it sees expression as a variable and not a function.

Order of precedence

It’s important to keep a few things in mind when declaring JavaScript functions and variables.

  • Variable assignment takes precedence over function declaration.
  • Function declarations take precedence over variable declarations.

Function declarations are hoisted over variable declarations but not over variable assignments.

Variable assignment over function declaration

var double = 22;  function double(num) {   return (num*2); }  console.log(typeof double); // Output: number 
Enter fullscreen mode Exit fullscreen mode

Function declarations over variable declarations

var double;  function double(num) {   return (num*2); }  console.log(typeof double); // Output: function 
Enter fullscreen mode Exit fullscreen mode

Even if we reversed the position of the declarations, the JavaScript interpreter would still consider double a function.

Hoisting classes

JavaScript classes too can be loosely classified either as:

  1. Class declarations
  2. Class expressions

1. Class declarations

JavaScript class declarations are hoisted. However, they remain uninitialized until evaluation. This effectively means that you have to declare a class before you can use it.

var Frodo = new Hobbit(); Frodo.height = 100; Frodo.weight = 300; console.log(Frodo); // Output: ReferenceError: Hobbit is not defined  class Hobbit {   constructor(height, weight) {     this.height = height;     this.weight = weight;   } } 
Enter fullscreen mode Exit fullscreen mode

So, as far as class declarations go, to access the class declaration, you have to declare first.

class Hobbit {   constructor(height, weight) {     this.height = height;     this.weight = weight;   } }  var Frodo = new Hobbit(); Frodo.height = 100; Frodo.weight = 300; console.log(Frodo); // Output: { height: 100, weight: 300 } 
Enter fullscreen mode Exit fullscreen mode

2. Class expressions

Much like their function counterparts, class expressions are not hoisted.

Here’s an example with the un-named or anonymous variant of the class expression.

var Square = new Polygon(); Square.height = 10; Square.width = 10; console.log(Square); // Output: TypeError: Polygon is not a constructor  var Polygon = class {   constructor(height, width) {     this.height = height;     this.width = width;   } }; 
Enter fullscreen mode Exit fullscreen mode

Here’s an example with a named class expression.

var Square = new Polygon(); Square.height = 10; Square.width = 10; console.log(Square); // Output: TypeError: Polygon is not a constructor   var Polygon = class Polygon {   constructor(height, width) {     this.height = height;     this.width = width;   } }; 
Enter fullscreen mode Exit fullscreen mode

The correct way to do it is like this:

var Polygon = class Polygon {   constructor(height, width) {     this.height = height;     this.width = width;   } };  var Square = new Polygon(); Square.height = 10; Square.width = 10; console.log(Square); 
Enter fullscreen mode Exit fullscreen mode

Conclusion

Let’s summaries what we’ve learned so far:

  1. While using es5 var, trying to use undeclared variables will lead to the variable being assigned a value of undefined upon hoisting.
  2. While using es6 let and const, using undeclared variables will lead to a Reference Error because the variable remains uninitialized at execution.

Therefore,

  1. We should make it a habit to declare and initialize JavaScript variables before use.
  2. Using strict mode in JavaScript es5 can help expose undeclared variables.

I hope this article will serve as a good introduction to the concept of hoisting in JavaScript and spur your interest regarding the subtleties of the JavaScript language.

beginnersjavascriptreactwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 2k
  • Popular
  • Answers
  • Author

    ES6 - A beginners guide - Template Literals

    • 0 Answers
  • Author

    Understanding Higher Order Functions in JavaScript.

    • 0 Answers
  • Author

    Build a custom video chat app with Daily and Vue.js

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.