Prashanth C
Prashanth C

Reputation: 161

Why can you call on a function before it is declared and defined in one's script?

Following is some sample code of what I mean, taken from How to JS Animate (W3 Schools via W3schools.com).

Sample code:

function myMove() 
    {
          var elem = document.getElementById("myAnimation");
          var pos = 0;
          var id = setInterval(frame, 10);
          function frame()
          {
            if (pos == 350) {
              clearInterval(id);
            } else {
              pos++;
              elem.style.top = pos + 'px';
              elem.style.left = pos + 'px';
            }
          }
    } 

In context of the specific sample code above, I will raise the same question for concreteness sake.

Question:

Why can frame() be called by setInterval(frame,x) even though its first defined and declared after the assignment of setInterval() to the "id" variable deceleration?

Background:
I'm a self-taught C/C++ coder venturing into the world of web development. I've read about "hoisting" of variables for ES6, but I'm not entirely sure if this happens for functions as well. In C++ and C, you can't do this (from my understanding)! So, Please, someone, help me out!

Thank you!

Upvotes: 1

Views: 2255

Answers (4)

Prashanth C
Prashanth C

Reputation: 161

It is hoisting (a programming concept).

In JavaScript:

  • hoisting applies to functions
  • hoisting applies to "var"-type variables
  • hoisting does not apply to:
    • "let" type variables
    • "const" type objects/constants
    • "expressions" (unsure of meaning)

The link he provided is here, which explains a lot of the nuances: Hoisting on MDN

Upvotes: 0

Daniel
Daniel

Reputation: 15453

I believe with function declarations:

growl();

function growl() {
    return "Grr!";
}

JavaScript will run through the function declaration code first.

However, if I create this type of function:

hoot();

var hoot = function() {
    return "hoo! hoo!";
}

I will get:

TypeError: hoot is not a function

Why? Because we are using a function expression, they are not entirely hoisted. I say not entirely because JavaScript has read var hoot but it does not know the value of it, so it would set it to undefined and it would try to call undefined.

So the variable is hoisted, but the value is not.

What happens if I try it this way?

hoot();

let hoot = function() {
    return "hoo! hoo!";
}

I would get the following error:

ReferenceError: Cannot access 'hoot' before initialization

Why? Because let hoot variable declaration is not hoisted. So the error is saying we cannot use this function before it's declared. We cannot access hoot before it can exist, which makes sense, but you can with function declarations and when you use var. It's an interesting quirk of JavaScript and let and const exists to remedy these kinds of unintended consequences such as hoisting.

Upvotes: 1

Akshay Bande
Akshay Bande

Reputation: 2587

When your code will go through phases,

  1. Compilation
  2. Execution

In the compilation phase Hoisting will occur, in which all the function declarations will be taken to the top of their scope.

When your code is compiled by JS engine it will be treated as:

function myMove() 
{   

    function frame()
    {
        if (pos == 350) {
            clearInterval(id);
        } else {
            pos++;
            elem.style.top = pos + 'px';
            elem.style.left = pos + 'px';
        }
    }
    var elem;
    var pos;
    var id;

    elem = document.getElementById("myAnimation");
    pos = 0;
    id = setInterval(frame, 10);

} 

Note:

  1. All functions are hoisted before variables.
  2. Variables declared with let and const are not eligible for hoisting.
  3. Function expressions are not eligible for hoisting.

Edit: Function expressions:

A JavaScript function can also be defined using an expression.

A function expression can be stored in a variable:

var x = function (a, b) {return a * b};

After a function expression has been stored in a variable, the variable can be used as a function. Functions stored in variables do not need function names. They are always invoked (called) using the variable name

Upvotes: 2

Long Tran thanh
Long Tran thanh

Reputation: 86

Thank to Hoisting. Imagine your function definition will be moved to the top of the script. That's it, you can call frame() though its definition is down below

Upvotes: 2

Related Questions