Hoisting – please read this , if you really want to understand its behaviour in JavaScript (2 ed.)
Tags: javascript, hoisting
Published: 2021-11-24 20:03:01

> If you'd like an article please give a thumb as your encouragement is my encouragement as well . Thank you ! 

---

### **VARiables**

Variables declared upon `var` and function declaration inclusively , are said to be lifted to the top of the scope as where it had been declared in . `The true reality : nothing is lifted up` . <b>Hoisting</b> *in JavaScript refers to the process whereby the just-in-time (JIT) compiler allocates memory for variables & function declarations prior to execution of the remaining code , thus creating the illusion of “moving” to the top* . Worth to mention , rather than function declaration, **function expression ARE NOT hoisted** ! 

**Example 1**

```javascript
console.log(age); 
var age;
// undefined (no error thrown)
```
### **LETs & CONSTs**

Variables declared with `let` and `const` are hoisted as well , but unlike variables declared with `var` , let & const are not initialized (*a.k.a. assigned*) with the value of `undefined` . Last sentence is quite jeopardizing . Let me fix myself . It appears variables declared upon using keyword `let` also initializes with value of undefined , but it suffers from so-called temporal-dead-zone (TDZ) [1] . 

**Example 2**

```javascript
console.log(age); // TDZ
let age = 101;
// ReferenceError : { Cannot access 'age' before initialization
```

To fix temporal dead zone (TDZ) issue , let's tweak Example 2 as so :

**Example 2.1**

```javascript
// TDZ
let age;
console.log(age); // # no more error
// undefined
```

Variables declared with `const` follows similar pattern of `let` except it explicitly MUST go with some initial value , otherwise `Missing initializer in const declaration` will be thrown .

---

### Differences between the keywords used in global context (window) :

| **var**                | vs. | **let**                 |
|------------------------|-----|-------------------------|
| var gglobal = "global" | --  | let lglobal == "global" |
| console.log(gglobal)   | --  | console.log(lglobal)    |
| "global"               | --  | undefined               |

---

### **Definition of "declared global(ly)" exploit**

Developers, especially newbies, like to play with words stating that if declared with `var` it's global, you bet ! Technically it depends ! Let's examine the following Example 3 :

**Example 3**

```javascript
var mostGlobal = this; // use keyword THIS (lower-cased) to test scope binding
console.log("global (at most): ", mostGlobal === window);

function lexical(){
    console.log("global scope got penetrated into", mostGlobal)
    var innerThis = this; // not available outside function – that's what it means then said that VAR are FUNCTION-SCOPED
    var innerWindow = window; // not available outside function – that's what it means then said that VAR are FUNCTION-SCOPED
    // console.log(private) // # uncomment to reproduce error i.e. ReferenceError: private is not defined
    function closure() {
    console.log("global scope got penetrated into", mostGlobal)
    // function with preserved data is called closure
    // let's add own variable to closure that will be available within closure and deeper nested functions , but not outside the function variable was declared :
    var private;
    console.log(innerThis, innerWindow, innerThis === innerWindow);
    }
closure();
}
lexical();
```

> NOTE : Exactly due to most globally declared variables such as `mostGlobal` are most dangerous due to brutal penetration through all levels of functions whenever such functions executed .

> RULE OF THUMB : avoid declaring variables with `var` , use either let or const (at best) although the remaining has its own pros & cons (*not discussed in this article*) 

--- 

> **Concluded** : variables declared within global scope (window) using keyword **var** e.g. `var globalMost` or `window.globalMost` automatically become global(-scoped) . Conversely, declared so within N-tuple nested function , it becomes function-scoped by nature which bears resemblance (as if) declared globally , although it's not anymore as it's not available outside the function unless within the function where it was declared and the nested inner N-tuples (Example 3) .

--- 

Hopefully you got introduced what really Hoisting is about . I can see myself this article lacks explanation in function-scoped (var) AND block-scoped (let & const) . However , this article intended to explain about Hoisting as titled specifically , not Scoping , nevertheless the following two are strongly coupled. Meanwhile article about Scoping or relevant topic will be in process of baking , you can find more about the Scoping reading this article by well known dev Tania Rascia published on Digital Ocean [2]

Thanks for reading and see you in the next one ! 

---
<u>References</u>

- [1] [TDZ by D. Pavlutin](https://dmitripavlutin.com/javascript-variables-and-temporal-dead-zone/)
- [2] [Scopes by Tania Rascia](https://www.digitalocean.com/community/tutorials/understanding-variables-scope-hoisting-in-javascript)