Demystifying Function Declarations Within Conditional Blocks

Corina MurgCorina Murg
2 min read

In the two previous posts in this series about hoisting, we talked about how function declarations - using the function keyword - are hoisted along with their definitions. This means we can call such a function BEFORE its code even appears, and it will execute.

Now we will delve into the nuances related to hoisting function declarations within conditional blocks. The path our function declaration might take is based on the environment in which we operate.


In many languages, when you declare a function inside a conditional block (like an if statement), it's conditionally created, i.e., the function is only declared if the block is executed.

JavaScript behaves differently (of course!) when it comes to function declarations (using the function keyword) inside conditionals.

Here's a simple example:

if (false) {
    function testFunction() {
        console.log("This is a test function.");
    }
}
testFunction();

Expectation: Since the condition is false, the code inside won't run, and thus the function won't be declared.

The reality of JavaScript: it depends!

In some environments, calling testFunction() after this block might work, because of hoisting.

Here's how this behavior varies depending on the JavaScript environment:

  1. ES5 and non-strict mode: The function declaration is hoisted out of the block and to the top of the enclosing function or global scope, irrespective of the conditional. This means testFunction would be available both before the block's start and after its end, throughout the enclosing function or global scope.

  2. ES6 (ES2015) and later in strict mode: Block-level function declarations are now defined per the ES6 specification, which means the function is block-scoped, just like let and const. So in this case, trying to call testFunction outside the block will throw an error because the function was not hoisted outside of the block.

This is a subtle yet important distinction, and the reason why we often see recommendations to avoid using function declarations inside blocks (instead, use function expressions or arrow functions).

Main Takeaway

While traditional function declarations are hoisted to the top of their scope, when used inside conditional blocks, their behavior can vary based on the ECMAScript version and mode (strict vs. non-strict).

Resources

  1. MDN Documentation on Functions Declared within Block Scopes

  2. Blog post: The Curious Case of JavaScript Hoisting

  3. Blog post: The Temporal Dead Zone

0
Subscribe to my newsletter

Read articles from Corina Murg directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Corina Murg
Corina Murg

I am a self-taught software engineer with a background in math teaching. As a teacher my focus was on creating learning experiences that were inclusive and accessible. For that reason, the frontend's concern with accessible web products deeply resonates with me. I am excited to collaborate on projects with developers from all over the world, and engage in conversations about our responsibility to ensure that every user feels seen and valued. I believe in a web where everyone has a place!