How JS hoisting works within functions?
JavaScript hoisting within functions means that the declaration of variables are moved to the top of the function block. When you enter foo()
, var boo
is redeclared instantly even though you have not reached it (because the JS engine knows that this declaration exists within the function). Accordingly, the reason that it is undefined is because it has only been declared, you don't assign a value until the following line.
In reality, this is not a situation you should find yourself in if you declare variables in an appropriate scope and don't redeclare variables with the same name, but I understand your curiosity.
You can read more about this here.
Is there a purpose to hoisting variables?
"Hoisting" is necessary for mutually recursive functions (and everything else that uses variable references in a circular manner):
function even(n) { return n == 0 || !odd(n-1); }
function odd(n) { return !even(n-1); }
Without "hoisting", the odd
function would not be in scope for the even
function. Languages that don't support it require forward declarations instead, which don't fit into JavaScripts language design.
Situations that require them might arise more often that you'd think:
const a = {
start(button) {
…
button.onclick = e => {
…
b.start(button);
};
}
};
const b = {
start(button) {
…
button.onclick = e => {
…
a.start(button);
};
}
};
javascript hoisting: what would be hoisted first — variable or function?
Given var foo = something
, only the variable declaration is hoisted.
This means that var foo
is hoisted but the foo = something
will run in the reading order.
Given function foo() {}
, the variable declaration and function assignment are both hoisted. This creates the variable foo
and gives it the value of the function.
If you have both of the above, then you declare the variable twice (for no extra effect) and assign it the value of the function (as that is the only assignment).
So in your second example…
The function declaration is hoisted, so f(); // - first f
calls that.
The assignment of the function expression is not hoisted, but f(); // ** - second f
appears after it in normal reading order, so the second call to foo()
hits that.
JavaScript variable hoisting behavior
In general, this is how hoisting works:
- the declaration of the variable is moved to the top
- the variable is initialized with a special "hoisted" value
- when the program reaches the
var/let/const
line, the variable is re-initialized with the value mentioned on that line (orundefined
if there's none).
Now, your example can be simplified down to this:
console.log(a)let a = 150
Hoisted' JavaScript Variables
Quoting MDN Docs on var
hoisting,
Because variable declarations (and declarations in general) are processed before any code is executed, declaring a variable anywhere in the code is equivalent to declaring it at the top. This also means that a variable can appear to be used before it's declared. This behavior is called "hoisting", as it appears that the variable declaration is moved to the top of the function or global code.
So, in your case, JavaScript knows that a local variable (not the one declared outside) x
is defined somewhere in the function, but it does not know the actual value of it until the execution reaches an assignment statement which assigns to x
. (Declarations are processed during the compile time and assigments are done in the execution time) Till the assignment is done, the default value undefined
will be used. Since undefined
is falsy, the condition
if (!x) {
is satisfied and the assignment statement is executed. That is why you are getting hoisted
in the alert box.
Let's say you have not declared x
inside the function,
var x;
var y = function () {
if (!x) {
x = 'hoisted';
}
alert(x);
}
y();
alert(x);
Here, since x
is not declared anywhere within the function, at runtime, JavaScript will look for x
in the higher scopes. In this case, it finds it right outside the function. So, that x
will be used. Since you assigned hoisted
to x
, the inner alert
will also say hoisted
and after leaving the function, alert(x)
will also alert hoisted
.
Why does JavaScript hoist variables?
As Stoyan Stefanov explains in "JavaScript Patterns" book, the hoisting is result of JavaScript interpreter implementation.
The JS code interpretation performed in two passes. During the first pass, the interpreter processes variable and function declarations.
The second pass is the actual code execution step. The interpreter processes function expressions and undeclared variables.
Thus, we can use the "hoisting" concept to describe such behavior.
Related Topics
Method for Streaming Data from Browser to Server via Http
How to Add/Subtract Dates with JavaScript
What Does the Function Then() Mean in JavaScript
Merge Two Arrays So That the Values Alternate
Calling a JSON API with Node.Js
What Is the Dollar Sign in JavaScript, If Not Jquery
Does Using $This Instead of $(This) Provide a Performance Enhancement
Jqgrid: Change Background Color of Row Based on Row Cell Value by Column Name
Replacing Spaces with Underscores in JavaScript
Puppeteer Page.Evaluate Queryselectorall Return Empty Objects
Returning a Value from Callback Function in Node.Js
How to Check If the Url Contains a Given String
JavaScript - Return String Between Square Brackets
JavaScript Runtime Complexity of Array Functions
How to Implement Custom Sort to a Specific Column After Jqgrid Has Been Generated
Why Use Object.Prototype.Hasownproperty.Call(Myobj, Prop) Instead of Myobj.Hasownproperty(Prop)