---
# System prepended metadata

title: JavaScript核心篇 - Hoisting、暫時性死區TDZ
tags: [hoisting, ' TDZ', ' 暫時性死區']

---

---
title: JavaScript核心篇 - Hoisting、暫時性死區TDZ
tags: hoisting, 暫時性死區, TDZ
description:
---
Hoisting、暫時性死區TDZ
---
- 函式的宣告**放前面**
```javascript=
function eat() {
  console.log ('吃飯');
}
function sleep() {
  console.log('睡覺')
}
eat();
sleep();
```
- 函式的宣告**放後面**
```javascript=
eat();
sleep();
function eat() {
  console.log ('吃飯');
}
function sleep() {
  console.log('睡覺')
}
```
:::success
函式的宣告放前面，或放後面，結果**都一樣**。

不過，宣告可以放在後面，就**僅限函式**而已。

宣告**為什麼**可以放在後面，這就叫做==Hoisting==。
:::

- console.log()印出的結果，a為`undefined`， b為`ƒ fn(){console.log('fn');}` 。
- 這就是`Hoisting`。

```javascript=
console.log(a, fn);

var a = 1;

function fn() {
  console.log('fn');
}
```
實際運行狀況
```javascript=
// 1.創造階段（建立記憶體空間）,函式優先
function fn() {
  console.log('fn');
};
var a;
// 2.執行階段
a = 1;
console.log(a, fn);
```
:::success
Hoisting有分 **創造階段**（建立記憶體空間）、**執行階段**。
:::
- 範例1
```javascript=
console.log(a);
var a = 2;
console.log(a);
```
- 實際運行
```javascript=
// 1.創造階段(建立記憶體空間）
var a;

// 2.執行階段
console.log(a);    // undefined
a = 2;
console.log(a);    // 2
```
<br>

- 範例2
```javascript=
var a = 1;
function a() {
  console.log('123');
}
console.log(a);
```
- 實際運行
```javascript=
// 1.創造階段（建立記憶體空間）,函式優先
function a() {
  console.log('123');
}
var a;
// 2.執行階段
a = 1;
console.log(a);    //     取得變數a的值1
```
<br>

- 範例3
```javascript=
console.log(a);
var a = 1;
function a() {
  console.log('123');
}
```
- 實際運行
  - 執行階段`console.log()`印出變數`a`的時候，變數`a`尚未被賦予`1`。
  - 這時候`console.log()`印出的是`function a()`。
```javascript=
// 1.創造階段（建立記憶體空間）,函式優先
function a() {
  console.log('123');
}
var a;
// 2.執行階段
console.log(a);
a = 1;
```

### TDZ：暫時性死區
:::success
**無法**在宣告let、const之前，試圖存取let、const的值。
:::
```javascript=
{
  console.log(a);
  let a = 1;
}
```
![](https://i.imgur.com/SAheurR.png)

`let`、`const`也有類似Hoisting的創造階段、執行階段，只不過`let`、`const`為了保護開發者，**禁止在宣告let、const之前，試圖存取let、const的值**。

所以`let`、`const`的`Hoisting`現象，改為**TDZ：暫時性死區**
<br>

### undefined、not defined的差異
- **not defined**
因為沒有定義a，所以會顯示`a is not defined`，然後==程式碼運行會中斷==在此處。

![](https://i.imgur.com/bYik3At.png)

```javascript=
console.log(a);
console.log('123');    // 不會繼續運行
```

- **undefined**
有把a定義為變數，但**未賦予值**，所以`console.log()`印出`undefined`
```javascript=
let a;
console.log(a);    // undefined
console.log('123');    // 會繼續運行
```