# hoisting

[JS](https://lochiwei.gitbook.io/web/js) ⟩ [scope](https://lochiwei.gitbook.io/web/js/scope) ⟩ hoisting

{% hint style="success" %} <mark style="color:purple;">**hoists**</mark> [id](https://lochiwei.gitbook.io/web/js/grammar/token/id "mention")s to the <mark style="color:yellow;">**top**</mark> of a [](https://lochiwei.gitbook.io/web/js/scope "mention") (at [compile-time](https://lochiwei.gitbook.io/web/js/compile/compile-time "mention"))

* [var](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/var "mention") - <mark style="color:yellow;">**declaration**</mark> hoisted, <mark style="color:yellow;">**value**</mark> initialized to "[undefined](https://lochiwei.gitbook.io/web/js/val/prim/undefined "mention")".
* [let-const](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/let-const "mention") - <mark style="color:yellow;">**declaration**</mark> hoisted, <mark style="color:yellow;">**value**</mark> "[<mark style="color:red;">**uninitialized**</mark>](https://lochiwei.gitbook.io/web/js/variable/access/uninitialized)"❗️
* [require-initial](https://lochiwei.gitbook.io/web/js/variable/declare/const/require-initial "mention") - <mark style="color:red;">**must**</mark>**&#x20;**<mark style="color:yellow;">**have**</mark> with [initial-value](https://lochiwei.gitbook.io/web/js/variable/declare/initial-value "mention")❗️
* [function](https://lochiwei.gitbook.io/web/js/scope/hoist/function "mention") - <mark style="color:yellow;">**declaration**</mark> hoisted, <mark style="color:yellow;">**value**</mark> initialized to a [func](https://lochiwei.gitbook.io/web/js/val/func "mention").
  {% endhint %}

{% tabs %}
{% tab title="⭐️ 重點" %}
{% hint style="warning" %}
[lexical-declaration](https://lochiwei.gitbook.io/web/js/grammar/declare/lexical-declaration "mention") ( [let](https://lochiwei.gitbook.io/web/js/variable/declare/let "mention") / [const](https://lochiwei.gitbook.io/web/js/variable/declare/const "mention") / [class](https://lochiwei.gitbook.io/web/js/val/class "mention") )&#x20;

* is "[<mark style="color:red;">**uninitialized**</mark>](https://lochiwei.gitbook.io/web/js/variable/access/uninitialized)" <mark style="color:yellow;">**first**</mark> (at [compile-time](https://lochiwei.gitbook.io/web/js/compile/compile-time "mention")).
* then <mark style="color:yellow;">**initialized**</mark> to its [initial-value](https://lochiwei.gitbook.io/web/js/variable/declare/initial-value "mention") (<mark style="color:yellow;">**when**</mark> execution reaches its <mark style="color:yellow;">**declaration**</mark> at [runtime](https://lochiwei.gitbook.io/web/js/compile/runtime "mention")):exclamation:
* there's a [tdz](https://lochiwei.gitbook.io/web/js/variable/access/tdz "mention") <mark style="color:yellow;">**between**</mark> these <mark style="color:yellow;">**two states**</mark>, be aware:exclamation:
  {% endhint %}

{% hint style="warning" %} <mark style="color:purple;">**hoisting**</mark>**&#x20;**<mark style="color:yellow;">**priority**</mark>

* [declare](https://lochiwei.gitbook.io/web/js/val/func/declare "mention") is hoisted <mark style="color:yellow;">**first**</mark> ([function](https://lochiwei.gitbook.io/web/js/scope/hoist/function "mention")).
* <mark style="color:yellow;">**then**</mark> [variable](https://lochiwei.gitbook.io/web/js/scope/hoist/variable "mention") ([var](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/var "mention") / [let-const](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/let-const "mention")).&#x20;

:point\_right: [first](https://lochiwei.gitbook.io/web/js/scope/hoist/function/first "mention")
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}

* [variable](https://lochiwei.gitbook.io/web/js/scope/hoist/variable "mention")
  * [let-const](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/let-const "mention")
  * [var](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/var "mention")
    * [fe-not-hoisted](https://lochiwei.gitbook.io/web/js/scope/hoist/variable/var/fe-not-hoisted "mention"):exclamation:
* [function](https://lochiwei.gitbook.io/web/js/scope/hoist/function "mention")
  * [first](https://lochiwei.gitbook.io/web/js/scope/hoist/function/first "mention"):exclamation:
* <mark style="color:yellow;">**related topics**</mark>
  * [declare](https://lochiwei.gitbook.io/web/js/val/func/declare "mention")
  * [declare](https://lochiwei.gitbook.io/web/js/variable/declare "mention")
    {% endtab %}

{% tab title="🧨 雷區" %}
{% hint style="danger" %}
declared [variable](https://lochiwei.gitbook.io/web/js/variable "mention") <mark style="color:red;">**cannot**</mark> be accessed in the TDZ.
{% endhint %}

* replit：[hoisting & TDZ](https://replit.com/@pegasusroe/hoisting-and-TDZ#index.js)

```javascript
const { log } = console;

function hi() {
    
    var x = "Hello";

    // block scope
    {
        // ----------------------------------------------------------------
        // ⭐️ the compiler WON'T check if `x` is referenced in the TDZ
        //    at compile-time, but will cause run-time error when running❗
        // ----------------------------------------------------------------
        x = "Howdy";    // ╮
                        // ⭐️ Temporal Dead Zone (TDZ) for `x`
                        // ╯  (can't access `x` in this zone❗)
        
        let x = "Hi";   // ⭐️ `x` declared here❗
        log(x);
    }
    
}

log('hello');    // ✅ 'hello' (this is OK.)

hi();            // ⛔ run-time error
//
// ⛔ ReferenceError: 
//    Cannot access 'x' before initialization
//    (note: this is a runtime error❗)
```

{% endtab %}

{% tab title="👥 相關" %}

* [declare](https://lochiwei.gitbook.io/web/js/val/func/declare "mention")
* [declare](https://lochiwei.gitbook.io/web/js/variable/declare "mention")
  {% endtab %}

{% tab title="📗 參考" %}

* [ ] [ydkjs-scope-and-closures-v.2](https://lochiwei.gitbook.io/web/master/ref/book/you-dont-know-js-series-v.2/ydkjs-scope-and-closures-v.2 "mention") ⟩&#x20;
  * [ ] [Ch. 1](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch1.md#chapter-1-whats-the-scope) ⟩ [Hoisting](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch1.md#hoisting)
  * [ ] Ch. 5 ⟩ [Hoisting: Declaration vs. Expression](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch5.md#hoisting-declaration-vs-expression)
    {% endtab %}
    {% endtabs %}
