====== Java Script Hoisting ======
Hoisting in JavaScript is a behavior ;;;where variable and function declarations are moved, or "hoisted," to the top of their containing scope during the compilation phase;;;, before the code is executed. It's important to note that only the declarations are hoisted, not the initializations.
===== Variable hoisting =====
==== Using var keyword ====
;;;The variable declaration using var is hoisted, but the initialization is not.;; So, if you reference a variable before it's initialized, it will return undefined. \\
Example:
console.log(a); // undefined
var a = 5;
console.log(a); // 5
What's happening behind the scenes is something like this:
var a;
console.log(a); // undefined
a = 5;
console.log(a); // 5
Hoisting does not apply to variables declared with **let** and **const**; trying to access them before their declaration will result in a **ReferenceError**.
==== Without any keyword ====
;;;Variables that are declared without any keyword;;; (such as var, let, or const) ;;;are not hoisted;;;. Rather, **they become global variables** (if not already within a global scope), and their declaration and initialization happen at the line where they are assigned. \\
Example:
console.log(myVar); // ReferenceError: myVar is not defined
myVar = "abc";
console.log(myVar); // "abc"
In this case, **myVar** is not declared or initialized before the first console.log, so attempting to access it results in a **ReferenceError**.\\ \\
If you were to declare the variable without initializing it within a function, **it would be hoisted as a property of the global object** (such as window in a browser environment):
function myFunction() {
myVar = "abc";
}
myFunction();
console.log(window.myVar); // "abc" in a browser environment
This behavior can lead to unexpected results and make the code harder to understand and maintain.
===== Functions =====
;;;Function declarations are also hoisted, and this includes both the name and the code of the function.;;; \\
Example:
console.log(myFunction()); // "I'm hoisted!"
function myFunction() {
return "I'm hoisted!";
}
In this case, the entire function declaration is hoisted, so you can call it even before the point in the code where you define it.
;;;Function expressions (including arrow functions) are NOT hoisted like function declarations;;;, so their behavior is more like that of variables declared with **var**. \\
Only the variable declaration is hoisted, not the initialization with the function value. \\
Example:
console.log(myFunc); // undefined
console.log(myFunc()); // TypeError: myFunc is not a function
var myFunc = function() {
return "Hello!";
};
console.log(myFunc()); // "Hello!"
Since myFunc is defined using a function expression with var, the variable declaration is hoisted, but the initialization with the function value is not. So, at the point where we first try to call myFunc(), the variable myFunc is undefined, and attempting to call it as a function results in a **TypeError**.
Had myFunc been declared with let or const, attempting to access it before its declaration would result in a **ReferenceError** instead.