Computer Science

Javascript Hoisting

Javascript Hoisting is a mechanism in Javascript where variables and function declarations are moved to the top of their respective scopes during the compilation phase. This means that variables and functions can be used before they are declared in the code. However, only the declarations are hoisted, not the initializations.

Written by Perlego with AI-assistance

7 Key excerpts on "Javascript Hoisting"

  • Book cover image for: Building Applications with Spring 5 and Vue.js 2
    No longer available |Learn more

    Building Applications with Spring 5 and Vue.js 2

    Build a modern, full-stack web application using Spring Boot and Vuex

    wrapped by functions of the other three types of invoking, refers to the object that passed in as the first argument of the call() method.
    Passage contains an image

    Hoisting

    This is another thing that Java developers usually easily get confused. Hoisting is a metaphor for the way that JavaScript interpreters will lift  function declarations and 
    variable declarations to the top of their containing scope. So, In JavaScript, you can see something that is obviously wrong and will definitely break the compilation if you write that in Java, but it is totally valid in JavaScript.
    Let’s see an example:
    1. travel = 'No plan'; 2. var travel; 3. console.log(travel); // Is the output: undefined? 4. 5. function travel() {
    6. console.log('Traveling');
    7. } 8. travel(); // Is the output: Traveling?
    What will the output be when the JavaScript engine executes line 3 and 8? It is not undefined , and not Traveling . Line 3 is  "No plan" and line 8 is "Uncaught TypeError".
    Here is what the JavaScript interpreter sees when it processes the preceding code:
    1.
    // Function declaration moved to the top of the scope
    2. function travel() {
    3. console.log('Traveling');
    4. }
    5.
    // Variable declaration moved under function declaration
    6. var travel;
    7. travel = 'No plan';
    8.
    9. console.log(travel);
    // No plan
    10. travel();
    // Uncaught TypeError: travel is not a function
    JavaScript interpreter moves the function declarations up to the top, followed by variables declarations. Function expressions, for example, var travel = function(){} , are not lifted to the top as function declarations because they are also variable declarations.
    Let's see another example:
    1. function workout() {
    2. goToGym();
    // What will the output be?
    3. var goToGym = function () {
    4. console.log('Workout in Gym A');
    5. }
    6. return;
    7. function goToGym() {
    8. console.log('Workout in Gym B');
    9. }
    10. } 11. workout();
    What will the output be when line 2 is executed? It is "Workout in Gym B.". And here is what the interpreter sees when it processes the code:
  • Book cover image for: The JavaScript Workshop
    No longer available |Learn more

    The JavaScript Workshop

    A New, Interactive Approach to Learning JavaScript

    • Joseph Labrecque, Jahred Love, Daniel Rosenbaum, Nick Turner, Gaurav Mehla, Alonzo L. Hosford, Florian Sloot, Philip Kirkbride(Authors)
    • 2019(Publication Date)
    • Packt Publishing
      (Publisher)
    hoisting . Hoisting is a feature in which the interpreter moves the declarations of functions and variables to the top of their scope. This means that variable declarations are processed before any code is executed. When any scope is processed, first, the whole scope is searched for variable and function declarations. Then, the memory space is allocated for each of the variables and functions. After this, the body of the function or block is executed line by line.
    Note Hoisting only moves the declaration of the variables and functions, not the assignment. The assignment stays in the same position. Functions are hoisted first followed by the variables. So, it is a good practice to always first declare functions and then work on the implementation part: // 1st block { var name; console.log(name); name="gaurav" } // 2nd block { console.log(name); var name = "gaurav"; }
    Here, both of the blocks will return undefined . The output of both blocks is the same. The position of the declaration doesn't matter inside a block. The first block will not throw any errors relating to variables not being defined.

    The Difference between var and let

    In the case of var , after creating variable definitions, each of the variables is initialized with an undefined value, but in the case of let /const , the initialization to undefined does not happen until the line of the declaration. In the following code, the variable is in the Temporal Dead Zone and accessing it results in a reference error:
    // 1st block { let name; console.log(name); name="gaurav"; } // 2nd block { console.log(name); let name="gaurav" }
    Let's execute this and see the difference by observing the different outputs of var and let :
    Figure 13.11: let keyword usage
    In the preceding figure, you can see that if we use let , it throws a reference error. Let's look at the output using the var
  • Book cover image for: Single Page Web Applications
    Because variable declarations are always hoisted to the top of your functional scope, the best practice is to always declare your variables at the top of your functions, preferably with a single var statement. This matches what JavaScript does and avoids the type of confusion we illustrated in the previous figure.
    This scope and hoisting behavior can sometimes combine to cause some surprising behavior. Take the following code:
    When prison is executed and regular_joe is requested by console.log(), the JavaScript engine first checks whether regular_joe has been declared in the local scope. Because regular_joe isn’t declared in the local scope, the JavaScript engine then checks the global scope and finds that it’s defined there and returns that value. This is called walking up the scope chain. But what if the variable is also declared in the local scope?
    Does this seem counterintuitive or confusing? Let’s walk through the way JavaScript handles hoisting under the covers.

    2.3. Advanced variable hoisting and the execution context object

    All the concepts we’ve covered so far are generally regarded as necessary to know in order to be successful as a JavaScript developer. Let’s take it a step beyond that and see what happens under the hood: you’ll be one of the few who understands how JavaScript really works. We’ll start with one of JavaScript’s more “magical” features: variable and function hoisting.
    2.3.1. Hoisting
    Like all forms of magic, the trick becomes almost disappointing when the secret is revealed. The secret is that the JavaScript engine makes two passes over code when it comes into scope. On the first pass it initializes variables and on the second pass it executes code. I know, simple; I have no idea why it’s not usually described in these terms. Let’s go into more detail on what the JavaScript engine does during the first pass because it has some interesting repercussions.
  • Book cover image for: Secrets of the JavaScript Ninja, Second Edition
    In this case, because the identifier fun has been encountered in the second step when function declarations are registered, the value undefined isn’t assigned to the variable fun. This is why the first assertion, testing whether fun is a function, passes. After that, we have an assignment statement, var fun = 3, which assigns the number 3 to the identifier fun. By doing this, we lose the reference to the function, and from then on, the identifier fun refers to a number.
    During the actual program execution, function declarations are skipped, so the definition of the fun function doesn’t have any impact on the value of the fun identifier.
    Variable hoisting
    If you’ve read a bunch of JavaScript blogs or books explaining identifier resolution, you’ve probably run into the term hoisting—for example, variable and function declarations are hoisted, or lifted, to the top of a function or global scope.
    As you’ve seen, though, that’s a simplistic view. Variables and function declarations are technically not “moved” anywhere. They’re visited and registered in lexical environments before any code is executed. Although hoisting, as it’s most often defined, is enough to provide a basic understanding of how JavaScript scoping works, we’ve gone much deeper than that by looking at lexical environments, taking another step on the path of becoming a true JavaScript ninja.
    In the next section, all the concepts that we’ve explored so far in this chapter will help you better understand closures.

    5.6. Exploring how closures work

    We started this chapter with closures, a mechanism that allows a function to access all variables that are in scope when the function itself is created. You’ve also seen some of the ways closures can help you—for example, by allowing us to mimic private object variables or by making our code more elegant when dealing with callbacks.
    Closures are irrevocably tightly coupled with scopes. Closures are a straightforward side effect of the way scoping rules work in JavaScript. So in this section, we’ll revisit the closure examples from the beginning of the chapter. But this time you’ll take advantage of execution contexts and lexical environments that will enable you to grasp how closures work under the hood.
  • Book cover image for: HTML, CSS & JavaScript in easy steps
    Save the HTML document, then open it in your browser and launch the console to see values returned from functions
    The * asterisk character is the arithmetical multiplication operator in JavaScript.
    Assign Functions
    Functions are really useful in JavaScript as they can be called (“invoked”) to execute their statements whenever required, and the caller can pass different arguments to return different results.
    It is important to recognize that the JavaScript ( ) parentheses operator is the component of the call statement that actually calls the function. This means a statement can assign a function to a variable by specifying just the function name. The variable can then be used to call the function in a statement that specifies the variable name followed by the ( ) operator. But beware, if you attempt to assign a function to a variable by specifying the function name followed by ( ) the function will be invoked and the value returned by that function will be assigned.
    Variables that were declared using the older var keyword were also hoisted, but those declared with let or const are not hoisted.
    Function Hoisting
    Although scripts are read by the JavaScript interpreter in top-to-bottom order it actually makes two sweeps. The first sweep looks for function declarations and remembers any it finds in a process known as “hoisting”. The second sweep is when the script is actually executed by the interpreter. Hoisting allows function calls to appear in the script before the function declaration, as the interpreter has already recognized the function on the first sweep. The first sweep does not, however, recognize functions that have been assigned to variables using the let or const keywords!
    Anonymous Functions
    When assigning a function to a variable, a function name can be omitted as the function can be called in a statement specifying the variable name and the ( )
  • Book cover image for: Professional JavaScript for Web Developers
    • Matt Frisbie(Author)
    • 2019(Publication Date)
    • Wrox
      (Publisher)
    sum is created in the global context and continues to exist even after the function has completed, allowing you to access it later.
    NOTE   Initializing variables without declaring them is a very common mistake in JavaScript programming and can lead to errors. It's advisable to always declare variables before initializing them to avoid such issues. In strict mode, initializing variables without declaration causes an error.
    A var declaration will be brought to the top of the function or global scope and before any existing code inside it. This is referred to as “hoisting”. This allows you to safely use a hoisted variable anywhere in the same scope without consideration for whether or not it was declared yet. However, in practice, this can lead to legal yet bizarre code in which a variable is used before it is declared. Here is an example of two equivalent code snippets in the global scope:
    var name = "Jake"; // This is equivalent to: name = 'Jake'; var name;
    Here is an example of two equivalent functions:
    function fn1() { var name = 'Jake'; } // This is equivalent to: function fn2() { var name; name = 'Jake'; }
    You can prove to yourself that a variable is hoisted by inspecting it before its declaration. The hoisting of the declaration means you will see undefined instead of ReferenceError :
    console.log(name); // undefined var name = 'Jake'; function() { console.log(name); // undefined var name = 'Jake'; }
    Block Scope Declaration Using let
    Brand new to ES6, let operates much in the same way as var , but it is scoped at the block level—a new concept in JavaScript. Block scope is defined as the nearest set of enclosing curly braces {} . This means if blocks, while blocks, function blocks, and even standalone blocks will be the extent of the scope of any variable declared with let
  • Book cover image for: TypeScript: Modern JavaScript Development
    • Remo H. Jansen, Vilic Vane, Ivo Gabe de Wolff(Authors)
    • 2016(Publication Date)
    • Packt Publishing
      (Publisher)
    This might seem really confusing, but it is easy to understand once we know that, at runtime, all the variable declarations are moved to the top of a function before the function is executed. This behavior is called hoisting.

    Note

    TypeScript is compiled to JavaScript and then executed—this means that a TypeScript application is a JavaScript application at runtime, and for this reason, when we refer to the TypeScript runtime, we are talking about the JavaScript runtime. We will learn in depth about the runtime in Chapter 5 , Runtime .
    So, before the preceding code snippet is executed, the runtime will move the declaration of the variable bar to the top of our function: function foo() : void { var bar :number; if(true){ bar= 0; } alert(bar); } This means that we can use a variable before it is declared. Let's take a look at an example: function foo2() : void { bar = 0; var bar : number; alert(bar); } foo2();
    In the preceding code snippet, we have declared a function foo2 , and in its body, we have assigned the value 0 to a variable named bar . At this point, the variable has not been declared. In the second line, we are actually declaring the variable bar and its type. In the last line, we are displaying the value of bar using the alert function.
    Because declaring a variable anywhere inside a function (except another function) is equivalent to declaring it at the top of the function, the foo2 function is transformed into the following at runtime:
    function foo2() : void { var bar : number; bar = 0; alert(bar); } foo2();
    Because developers with a Java or C# background are not used to the function scope, it is one of the most criticized characteristics of JavaScript. The people in charge of the development of the ECMAScript 6 specification are aware of this and, as a result, they have introduced the keywords let and const .
    The let keyword allows us to set the scope of a variable to a block (if, while, for… ) rather than a function block. We can update the first example in this section to showcase how let
Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.