---
# System prepended metadata

title: JavaScript - VAR vs LET vs CONST
tags: [JavaScript]

---

# JavaScript - VAR vs LET vs CONST 

![var let const](https://i.imgur.com/cOS9EA3.png)


## :mag: 以 "宣告與賦值" 來看：

- **var** 為宣告"變數"
    - 宣告同時可以不賦予值，預設值為undefined
    - 賦予值之後，可以重新賦予新值
    - 可以重複地宣告同一個變數，宣告(將被提升的部分)會被忽略，但賦值不會
    
- **let** 為宣告"變數"
    - 宣告同時可以不賦予值，預設值為undefined
    - 賦予值之後，可以重新賦予新值
    - 只能在同一個作用域內宣告一次
    
- **const** 則是宣告"常數"，*constant* 的縮寫
    - 宣告同時必須賦予值
    - 賦予值之後，無法重新賦予常數新值(無法改變常數的值)
    - 只能在同一個作用域內宣告一次

### 宣告時不賦予值
:dart: **var**
```javascript=
var aVar;
console.log('aVar = ' + aVar);        // aVar = undefined
```
:dart: **let**
```javascript=
let aLet;
console.log('aLet = ' + aLet);        // aLet = undefined
```
:dart: **const**
```javascript=
const aConst;
console.log('aConst = ' + aConst);    // SyntaxError: Missing initializer in const declaration
```

### 賦予值之後，重新賦予新值
```javascript=
var aVar = 'a';
console.log('aVar = ' + aVar);        // aVar = a
aVar = 'b';
console.log('aVar = ' + aVar);        // aVar = b


let aLet = 'a';
console.log('aLet = ' + aLet);        // aLet = a
aLet = 'b';
console.log('aLet = ' + aLet);        // aLet = b


const aConst = 'a';
console.log('aConst = ' + aConst);    // aConst = a
aConst = 'b';
console.log('aConst = ' + aConst);    // TypeError: Assignment to constant variable
```

### 重複宣告
:dart: **var**
```javascript=
var aVar = 'a';
var aVar = 'b';
var avar;
console.log('aVar = ' + aVar);        // aVar = b
```
:dart: **let**
```javascript=
let aLet = 'a';
let aLet = 'b';        // SyntaxError: Identifier 'aLet' has already been declared
console.log('aLet = ' + aLet);
```
:dart: **const**
```javascript=
const aConst = 'a';
const aConst = 'b';    // SyntaxError: Identifier 'aConst' has already been declared
console.log('aConst = ' + aConst);
```

## :mag: 以"作用域"來看：

- var 為 function scope 
    - 以"函式"來分割變數的作用域

- let、const 為 block scope 
    - 以"區塊"來分割 變數/常數 的作用域( { } or ( ) )
        - ex. function、for、if、switch、while、try / catch

### :dart: var - Function Scope
```javascript=
function test(){
  var aVar = 'a';
  console.log('aVar = ' + aVar);    // aVar = a
}
test();
console.log('aVar = ' + aVar);    // ReferenceError: aVar is not defined
```
### :dart: let、const - Block Scope
```javascript=
for (let aLet = 0; aLet < 3; aLet++) {
  console.log('aLet = ' + aLet);     // aLet = 0 、 aLet = 1 、 aLet = 2
}

console.log('aLet = ' + aLet);    // ReferenceError: aLet is not defined
```
```javascript=
{
  const aConst = 'c';
  console.log('aConst = ' + aConst);    // aConst = c
}
console.log('aConst = ' + aConst);    // ReferenceError: aConst is not defined

```

## :mag: 以 " [Hoisting]() " 來看：

- var 
    - **宣告**的部分**會被提升**
    - 提升後會先被**初始化**為 undefined
    
- let、const 
    - **宣告**的部分**會被提升**
    - 被提升後則**不會**先被**初始化**
    - 在宣告前對其做存取，會產生[**暫時性死區**]()的問題

:::success
:bulb: var、let、const 都會被提升，差別在於**提升時初始化與否**
:::

:dart: **var**
```javascript=
console.log('aVar = ' + aVar);    // aVar = undefined
var aVar = 'a';
console.log('aVar = ' + aVar);    // aVar = a
```
:dart: **let**
```javascript=
console.log('aLet = ' + aLet);    // ReferenceError: Cannot access 'aLet' before initialization
let aLet = 'b';
```
:dart: **const**
```javascript=
console.log('aConst = ' + aConst);    // ReferenceError: Cannot access 'aConst' before initialization
const aConst = 'c';
```
## :mag: 以"存入全域物件"來看
在 Global Scope 中**賦值**，將被存入 **window** 這個**全域物件**中
```javascript=
//Golbal Scope

world = 'Hello!!!'
console.log(window.world);    //Hello!!!
```
### 若在 Global Scope 中宣告 變數/常數 並賦予值：
- var
    - 會 存入 **window** 中
- let 、 const
    - 不會 存入 **window** 中

:dart: **var**
```javascript=
//Golbal Scope

var aVar = 'aVar';
console.log('window.aVar = ' + window.aVar);    // window.aVar = aVar
```
:dart: **let**
```javascript=
//Golbal Scope

let aLet = 'aLet';
console.log('window.aLet = ' + window.aLet);    // window.aLet = undefined
```
:dart: **const**
```javascript=
//Golbal Scope

const aConst = 'aConst';
console.log('window.aConst = ' + window.aConst);    // window.aConst = undefined
```

<br><br><br><br><br>

參考如下：

> [[day21] YDKJS (Scope) : Hoisting ？ let 會 Hoist 嗎 ? - 更進一步解釋 let hosting](https://ithelp.ithome.com.tw/articles/10225604#:~:text=%E7%B5%90%E6%9E%9C%E7%A8%B1%E4%BD%9CReferenceError%20.-,%E6%9B%B4%E9%80%B2%E4%B8%80%E6%AD%A5%E8%A7%A3%E9%87%8B%20let%20hosting,-%E9%80%99%E6%99%82%E5%80%99%EF%BC%8C%E9%9D%88%E9%AD%82%E7%9A%84)

> [[JavaScript] Javascript 中的 Hoisting(提升)：幫你留位子 - let, const and Hoisting](https://medium.com/itsems-frontend/javascript-hoisting-589488622dd7#:~:text=%E6%8F%90%E5%8D%87%E8%87%B3%E5%A4%96%E9%9D%A2%E3%80%82-,let%2C%20const%20and%20Hoisting,-%E5%9C%A8%20W3C%20%E4%B8%AD)

> [W3School - JavaScript Hoisting](https://www.w3schools.com/js/js_hoisting.asp)

> [VAR vs LET vs CONST](https://pbs.twimg.com/media/EeVw-DOXgAAMtKk?format=jpg&name=900x900)


###### tags: `JavaScript`


