Reputation: 161
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
Reputation: 161
It is hoisting (a programming concept).
In JavaScript:
The link he provided is here, which explains a lot of the nuances: Hoisting on MDN
Upvotes: 0
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
Reputation: 2587
When your code will go through phases,
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:
let
and const
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
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