---
# System prepended metadata

title: Javascript筆記 變數提昇

---

# Javascript筆記 變數提昇

在JS有一個叫undefind的詞，代表著未定義
例如說你設了一個變數，卻沒有給他定義一個值，跑起來的時候就會是undefind

ex:
```var hello```

#沒有給他指定值，所以會跑出undefind

而變數提昇常見的情況常出現在var上面，這個跟ＪＳ運行的機制有關。

ex:
```javascript
console.log(hello)
var hello = 123
```
//在這種情況下會跑出undefind，這是不正常的，照理來說應該會找不到這個變數而出現hello is not defind 。而這個現象就是變數提昇。

# 建立期與執行期
JS在運轉時會進行兩個階段：

***建立期( Creation Phase )***：會進行兩件事情，第一步先註冊名稱，再來第二步進行初始化

***執行期( Execution Phase )***:執行函數，賦值（ex:a = 1)

因此在上面的例子：
```
console.log(hello)
var hello = 123
```
**建立期：**
    ```console.log(hello) ```
    ＃不啟動
    ```var hello = 123```
    ＃找到 hello這個變數，也就是只執行了var hello，宣告hello這個變數，然後接著初始化，這個當下還沒有賦值，所以先塞了一個undefind給他。

**執行期：**
    ```console.log(hello)```
    ＃這裡console.log(hello)被執行，由於上一步的 hello變數已經被初始化，但是還沒有賦值。console.log(hello)找得到hello這個變數，卻沒有找到他的值，所以會導致undefind。
    ```var hello = 123```
    ＃在這裡hello這個變數才會被賦予或者是說指定123這個值。

ex:
```javascript
console.log(hello)印出#undefind
var hello = 123
console.log(hello)#印出123
```

#用 let 宣告

ex:
```javascript
console.log(hello)
let hello = 123
```

**建立期：**
    ```console.log(hello)``` 
    ＃不啟動
```let hello = 123```
    #let用法與var最大的差別是在這裡，他只會走出第一步：註冊名字，let變數在這裡不會初始化。所以這時候這個變數只有名字，進入了暫時死區。
    **執行期：**
    ```console.log(hello)```
    ＃在這裡console.log(hello)被運行，他會找到一個名為hello的名字，但是hello在暫時死區，只有名字不會被讀取。因此會出現error initialization 沒有初始化。
    ```let hello = 123```
    ＃到了執行期，這時候變數hello會被賦值，而賦值這個行為就為這個變數進行了初使化。
所以這個let的變數會從暫時死區只有名字的存在，變成了被賦予值，能夠正常使用的變數



