---
description: lifts identifiers to top of scope.
---

# hoisting

[JS](..) ⟩ [scope]() ⟩ hoisting

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

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

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

* is "[<mark style="color:red;">**uninitialized**</mark>](../variable/access/uninitialized)" <mark style="color:yellow;">**first**</mark> (at [compile-time](../compile/compile-time "mention")).
* then <mark style="color:yellow;">**initialized**</mark> to its [initial-value](../variable/declare/initial-value "mention") (<mark style="color:yellow;">**when**</mark> execution reaches its <mark style="color:yellow;">**declaration**</mark> at [runtime](../compile/runtime "mention")):exclamation:
* there's a [tdz](../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](../val/func/declare "mention") is hoisted <mark style="color:yellow;">**first**</mark> ([function](hoist/function "mention")).
* <mark style="color:yellow;">**then**</mark> [variable](hoist/variable "mention") ([var](hoist/variable/var "mention") / [let-const](hoist/variable/let-const "mention")).&#x20;

:point\_right: [first](hoist/function/first "mention")
{% endhint %}
{% endtab %}

{% tab title="🔴 主題" %}
* [variable](hoist/variable "mention")
  * [let-const](hoist/variable/let-const "mention")
  * [var](hoist/variable/var "mention")
    * [fe-not-hoisted](hoist/variable/var/fe-not-hoisted "mention"):exclamation:
* [function](hoist/function "mention")
  * [first](hoist/function/first "mention"):exclamation:
* <mark style="color:yellow;">**related topics**</mark>
  * [declare](../val/func/declare "mention")
  * [declare](../variable/declare "mention")
{% endtab %}

{% tab title="🧨 雷區" %}
{% hint style="danger" %}
declared [variable](../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](../val/func/declare "mention")
* [declare](../variable/declare "mention")
{% endtab %}

{% tab title="📗 參考" %}
* [ ] [ydkjs-scope-and-closures-v.2](../../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 %}
