---
# System prepended metadata

title: 【自學筆記】關於JavaScipt的hoisting
tags: [javascript, front-end]

---

###### tags: `javascript`, `front-end`
# 【自學筆記】關於JavaScipt的hoisting

直接先看例子

一般來說，先宣告後變數就可以抓到他
```javascript=
var a=1
console.log(a)
// 1
```

如果還沒有先宣告就先呼叫，則會顯示undefined
```javascript=
console.log(a)
var a=1
// undefined
```

但如果是這樣呢，我一樣先呼叫他，但==後面沒有宣告==
```javascript=
console.log(a)
//var a=1
```
:::danger 
結果會是這樣！！![](https://i.imgur.com/tLCXrI1.jpg)
:::

<font style="font-weight:bold;font-size:20px">為什麼呢，不是跟第二個一樣都還沒宣告嗎</font>

這就要從Javascript到網頁上的編譯過程分成兩階段來說明，
第一為解析階段，解析完成後才是實際執行程式的階段
:::info
解析階段  「宣告提升，賦值不動」
:::
Javascript程式在解析階段的時候
會先把所有的變數宣告拉到最上面
也就是剛剛的
```javascript=
console.log(a)
var a=1
// undefined
```
在這個階段其實會是這樣
```javascript=
var a;
console.log(a)
// undefined
```
要注意的是，這個階段僅是把變數宣告往上提升了並==沒有賦值==

<font style="font-weight:bold;font-size:20px">除了變數，function也會被hoisting</font>

直接來看例子
```javascript=
HoistingTest()

function HoistingTest(){
    console.log("test")
}

// test
```
可以看到我先呼叫了`HoistingTest()`
然後才去定義他，但程式卻可以順利吐出 test 的結果

:::success
綜上所述，hoisting會將變數宣告、function定義提升
:::

<font style="font-weight:bold;font-size:20px">問題又來了！！</font>

既然變數宣告、function定義會被提升，那如果今天的寫法是這樣的話
```javascript=
aaa()

var aaa = function HoistingTest(){
    console.log("test")
}
```
宣告了一個變數，然後他是function，但在宣告前就呼叫了，會發生甚麼事情咧:thinking_face: 
.
.
.
.
![](https://i.imgur.com/Wyx4eHQ.jpg)

就跟前面提到的一樣，雖然我宣告aaa為一個function，但==aaa仍然是個變數==，
所以在解析階段的時候，前面的程式其實是會變成這樣
```javascript=
var aaa;

aaa()
```
所以我用`aaa()`函式呼叫當然被認為是not a function
因為這時候去`console.log(aaa)`的話，會跟前面一樣是undefined




---

*新手工程師的筆記，純粹記錄學了些啥東西
如果有前輩高人讀了我的文，文中有任何錯誤再麻煩指教指教*