Understand how lifting works in JavaScript

Hoisting is a JavaScript mechanism that allows you to access variables and functions before initializing them. Hoisting such a statement effectively puts it at the peak of its scope.


Learn all about how lifting works in JavaScript and how to best handle it to avoid errors in your code.


Lifting variables With var, let and const

Lifting is possible because JavaScript uses the JIT (Just-in-Time) compilation system, which analyzes your code to identify all variables within their respective scopes.

The JIT compiler then hoists all instances of variable declarations to the top of their scope when compiled. JavaScript only hoists variable declarations, not their initializations.

The behavior of variables, when hoisted, depends on the keyword you declare them with, as each keyword behaves differently.

var

Accessing an uninitialized variable declared with the var the keyword will return indefinite. For instance:

console.log(foo);  
var foo = 2;

The code above saves indefinite because it calls console.log before initializing the variable.

The JavaScript compiler visualizes the preceding block of code as follows:

var foo;
console.log(foo);
foo = 2;

When hoisted, variables obey JavaScript scoping rules. Javascript will just hoist a variable to the top of the scope you declared it in. Attempting to save the value of a variable outside of its declared scope will result in a Reference error. For example, if you declare a variable inside a function, it won’t be visible outside of that scope:

function myFunction() {
console.log(foo);
var foo = 10;
}

myFunction();
console.log(foo);

Trying to access a variable outside of its scope will result in a Reference error.

let and const

According to the MDN documentation on let and constant lifting, JavaScript also hoists variables declared with the let and constant key words. However, unlike variables declared with the var keyword, they are not initialized with a indefinite assess.

For instance:

function myFunction() {
console.log(foo);
console.log(bar);
console.log(baz);

var foo = 5;
let bar = 10;
const baz = 15;
}

myFunction();

You cannot access variables declared with the let and const keywords before initializing them with a value.

Lifting functions

JavaScript hoists functions the same way as variables. As with variables, it depends on how you declare them. For example, JavaScript hoists function declarations differently than function expressions.

A function declaration is a function declared with a name, while a function expression is a function whose name you can omit. For instance:

function foo() {
}

const bar = () => {
}

JavaScript hoists function declarations but not function expressions. For instance:

foo(); 
bar();


function foo() {
console.log(5);
}


var bar = function expression() {
console.log(10);
};

This code calls mad before declaring and initializing it as a function, but it still connects 5 at the Consol. However, trying to call bar leads to a Standard error.

Manage lifting

Being aware of lifting and the potential errors that could occur if mishandled can save you long hours of debugging. Here are some ways to handle lifting.

Declaring variables inside functions

Declare variables inside the functions that will access them. You won’t always be able to do this, because you might need a global variable that you can access in multiple functions. So be sure to only declare variables globally if you really need them.

Declare variables with let or const

You should always use the land etcfirst of all keywords instead of var keyword when declaring variables. This practice is beneficial when declaring local variables inside a function. Knowing the correct ways to declare variables in JavaScript reduces the chances of errors caused by lifting occurring in your code.

Declare variables at the top of their scope

Declare all your variables at the top of their respective scopes, before any other statements. This will ensure that the JavaScript compiler doesn’t have to hoist these variables to access them.

Using Strict Mode

Strict mode is a JavaScript mode that regulates bad syntax, optimizes the execution time of your code, and prohibits the abuse of JavaScript’s loosely typed syntax by throwing errors at compile time.

For example, in “sloppy mode”, due to lifting, you can access a variable outside of the initialized function, even though it has not been declared:

myFunction();
console.log(foo);

function myFunction() {
foo = 20;
}

In the code block above, JavaScript automatically declares mad and hoists it to the top of the global scope, ignoring the scope in which you initialized it.

You can use strict mode to fix this behavior and throw an error if you try to access the variable outside of its function scope.

Strict mode does not completely stop lifting. Instead, it prevents the most confusing and error-prone forms of lifting. It is still important to understand the general concept and lifting rules, even when using the safety net in strict mode.

To enable strict mode globally, declare the syntax at the top of your script file:

"use strict"; // or 'use strict'

To enable strict mode at a function level, declare the syntax at the top of a function body before any statements:

function myStrictFunction() {
"use strict";
}

If you declare strict mode at a function level, the setting will only apply to statements inside that function.

Declaring strict mode globally prevents access to variables outside their respective scopes:

"use strict";
myFunction();
console.log(foo);

function myFunction() {
foo = 20;
}

With strict mode enabled, the JavaScript compiler will throw my function() at the top of its scope without the undeclared variable.

Understand what affects lifting

Hoisting is quite unique to JavaScript and can be a very confusing behavior to understand. It can affect variables and functions, but there are ways to prevent it if you need to.

Several factors can affect lifting, so it’s best to avoid any occurrence of variable or function lifting in your code.

Comments are closed.