---
# System prepended metadata

title: Hoisting 提升
tags: [觀念, javascript, 單元筆記]

---

# Hoisting 提升

###### tags: `單元筆記` `javascript` `觀念`

## 介紹

hoisting 看起來是單純地將變數和函式宣告，移動到程式的區塊頂端。
但實際上是變數和函數的宣告時就會先建立一個記憶體空間，運行程式碼時再賦值。
函式提升的優先級大於變數。
let 與 const 也有 hoisting。
但他們不會初始化為 undefined，而且在賦值之前試圖取值會發生錯誤（TDZ error）。

## 範例

ex01就好比是02

* ex01
```javascript=
console.log(a); // undefined
var a = '50';
```
* ex02
```javascript=
var a
console.log(a); // undefined
a = '50';
```

---

function expression 也會 hoisting

* 這種函式建立方法稱為：function expression 函式表達式
```javascript=
console.log(callSomeone); // undefined
callSomeone('Allen'); // callSomeone is not a function
var callSomeone = function (name) {
  console.log('打給 ' + name)
}
```
* 這種函式建立方法稱為：function declaration 函式陳述式 ( 直接以 function 開頭 )
```javascript=
console.log(callSomeone) // function
callSomeone('Allen'); // 打給 Allen
function callSomeone(name) {
  console.log('打給 ' + name)
}
```

## 說明

#### 為何需要?

讓 function 之間相互調用可行

```javascript=
function loop(n){
  if (n>1) {
    logEvenOrOdd(--n)
  }
}

function logEvenOrOdd(n) {
  console.log(n, n % 2 ? 'Odd' : 'Even')
  loop(n)
}

loop(10)
```

#### 如果沒有 Hoisting 會怎樣 ? 

1. 一定要宣告變數才能使用
2. 一定要宣告 function 才能使用
3. function 之間沒辦法互相調用

## 小記


應該就是一個基本觀念，當中會有一些底層細節，"目前"來說只要我有好好的宣告變數，基本上就不會有太大的影響。


:::info
好習慣 : 使用前先宣告
:::

## 參考
[MDN](https://developer.mozilla.org/zh-TW/docs/Glossary/Hoisting)
[我知道你懂 hoisting，可是你了解到多深？](https://blog.techbridge.cc/2018/11/10/javascript-hoisting/)
[鐵人賽：JavaScript Function 與 Hoisting](https://wcc723.github.io/javascript/2017/12/16/javascript-hoisting/)

