---
# System prepended metadata

title: 7/12(一) 每日任務
tags: [JavaScript, 六角四週帶你掌握 Vue.js 必要觀念]

---

# 7/12(一) 每日任務
https://hackmd.io/6RuBbl10Rwew6NScG5TfCA
###### tags: `JavaScript` `六角四週帶你掌握 Vue.js 必要觀念`
2021.7.14（Wed.）
:::success
### ● 題目
****
從 var 切換到 let, const 

>請將此段 var 宣告改為 let, const
```js
var HexSchool = '六角學院';
var HexSchoolAge = 5;
var course = {
  JavaScript: 2500
}
var HexSchoolGroup = {
  teacher: 'Casper',
  assistant: 'Ray'
}

// 後續程式碼，請藉此判斷使用 Let or Const
HexSchool = '六角學院，帶你學到會的線上課程';
course.JavaScript = 2000;
HexSchoolGroup = {};
```
參考: ES6 Let, Const 介紹 [Youtube 影音](https://www.youtube.com/watch?v=FGdKdn_CnWo)
:::

:::info
## ● 筆記：
****
**首先，了解甚麼是Scope？**
中文常見的翻譯為「範疇、作用域」，而意思則為「變數可以被取用 (accessibility)，或者可以被看到 (visibility) 的有效範圍」<font color="bfbfbd">（Scope determines the accessibility (visibility) of variables.）。
</font>

**再來，要知道JS屬於Lexical Scope（語彙範疇）**
[Lexical Scope（語彙範疇）](https://hackmd.io/iItKGrwwS5ySX8C6yva4pg#3Lexical-Scope%EF%BC%88%E8%AA%9E%E5%BD%99%E7%AF%84%E7%96%87%EF%BC%89)也就是：「外層 Scope 無法取用內層變數，但內層 Scope 可以取用外層變數。」

**接著，在JS中主要有兩大類作用域：**
```
* 一是全域性Global Scope，一是區域性Local Scope

1. Global Scope
2. Local Scope：
   (a.)Function Scope
   (b.)Block Scope
   
```
**1. Global Scope**
變數在函式外宣告（declared），則為全域範疇（Global Scope）
利用var、const、let在函式外宣告變數皆可為全域範疇（Global Scope）

**2. Local Scope**
變數必須在特定範圍內才可以使用，而區域範疇（Local Scope）又分為函式範疇（Function Scope）以及區塊範疇（Block Scope）。
* **Function Scope：**
<font color="#c75032">由函式（function）來決定範疇（Scope）</font>
▲ 每一個函式都會創造一個新的範疇，函式外不可使用在函式中被宣告的變數。
▲ 利用var、const、let在函式外宣告變數皆可為全域範疇（Global Scope）

* **Block Scope：**
<font color="#c75032">由大括號來決定範疇（Scope）</font>
▲ 這是在ES6後，JS增加了兩個新keywords：let、const，才出現的範疇，所以區塊範疇的應用不適用於var上。
▲ 大括號所組成的範圍包含function、if判斷式、while,for迴圈、try...catch等等，或單純的大括號也算。

**最後，來對var、let、const做個比較**
**1. 比較表格：**

| 名稱  | 重複宣告變數名稱 | 先用變數再宣告 | Global Scope | Function Scope | Block Scope |
| ----- |:----------------:|:--------------:|:------------:|:--------------:|:-----------:|
| var   |        O         | O（hoisting）  |      O       |             O   |        X     |
| let   |        X         |       X        |      O       |              O  |     O        |
| const |        X         |       X        |      O       |           O     |      O       |

**2. var的補充說明：**
▲ 利用var宣告變數，只會有兩種範疇可能，一是Function Scope、一是Global Scope。

▲ 如果用var變數宣告在函式內，作用範圍則為Function Scope；如果用var變數宣告在函式外，作用範圍在則為Global Scope。

▲ var沒有Block Scope作用範例：
①雖然有大括號，但非函式
```javascript=
{var team = "teamOne"}
console.log(team) //teamOne
```
②有函式的大括號
```javascript=
function printTeam(){
    if(true){
        var team = teamOne
        console.log(team) //teamOne
    }
}
printTeam()
console.log(team) //undefined
```
從以上範例可知，單純的大括號對於var沒有辦法形成一個範疇/作用域，只有函式可以。而對於let、const，只要利用大括號包起來，即成立Block Scope。

**3. 為甚麼var可以先使用再宣告？**
在JS中，不管你在函式中哪一行用var宣告變數，一律視為在函式中的第一行宣告，也就是說不論宣告var變數在哪，var宣告的動作一律被提升（hoisting），因此這動作稱之為「hoisting」。

但是只有宣告才有hoisting，賦值並沒有hoisting，舉例來說：
```javascript=
function printTeam(){
    console.log(team) //undefined
    var team = "teamOne"
    console.log(team) //teamOne
}
```
上述程式碼相當於：
```javascript=
function printTeam(){
    var team
    console.log(team) //undefined
    var team = "teamOne"
    console.log(team) //teamOne
}
```
這是因為在第一次console.log(team)時，team這個變數被使用了，但你在下一行才宣告變數var team = "teamOne"，所以它就自動提升在第一次console.log(team)之前，但他只會提升var team（宣告），而非提升整個var team = "teamOne"（賦值）。

**4. 函式的hoisting？**
hoisting在函式中，可以運用在兩個函數需要互相呼叫彼此的狀態，也就是 A() 裡面會呼叫到 B()，而 B() 裡面會呼叫的 A() 的遞迴狀況。

如下：
```javascript=
function isEven(n) {
  if (n === 0) return true;
  return isOdd(n - 1);
}

function isOdd(n) {
  if (n === 0) return false;
  return isEven(n - 1);
}

isEven(10); // true
```

**5. var、let、const**
利用let、const去替代var，而使用時機則是：
▲ let：會變化的變數
▲ const：不會變化的變數，例如說：pi=3.14
:::

:::warning
## ● 答案：
****
```js
let HexSchool = '六角學院';
const HexSchoolAge = 5;
const course = {
  JavaScript: 2500
}
let HexSchoolGroup = {
  teacher: 'Casper',
  assistant: 'Ray'
}

// 後續程式碼，請藉此判斷使用 Let or Const
HexSchool = '六角學院，帶你學到會的線上課程';
course.JavaScript = 2000;
HexSchoolGroup = {};
```
解釋：
1. 「HexSchool = '六角學院'」變成「HexSchool = '六角學院，帶你學到會的線上課程'」，因為let才能改值，所以用let。
2. HexschollAge 沒變更到所以用常數宣告
3. course物件改屬性可用 const
4. HexSchoolGroup 改了整個物件，所以用let
:::

:::danger
## ● 參考資料：
****
1. [JavaScript基本功修練：Day5 - 宣告變數 - let、const、var](https://ithelp.ithome.com.tw/articles/10240708)
2. [你不可不知的 JavaScript 二三事#Day8：var 掰掰 —— ES6 更嚴謹安全的 let 和 const](https://ithelp.ithome.com.tw/articles/10203715)
3. [ECMAScript6 入門：var、let、const 差異過去常用的 var、window](https://w3c.hexschool.com/blog/530adff5)
4. [之前的上課筆記](https://hackmd.io/iItKGrwwS5ySX8C6yva4pg)
5. [JS 原力覺醒 Day04 - Function Scope / Block Scope](https://ithelp.ithome.com.tw/articles/10217481)
6. [[教學] JavaScript 中的 Hoisting 是什麼意思？let const var 的差異居然是這個？](https://shubo.io/javascript-hoisting/)==<font color="red">推薦</font>==
7. [MDN：var](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Statements/var)
8. [w3c：scope](https://www.w3schools.com/js/js_scope.asp)
9. [[JavaScript] Javascript 的作用域 (Scope) 與範圍鏈 (Scope Chain)：往外找](https://medium.com/itsems-frontend/javascript-scope-and-scope-chain-ca17a1068c96)
:::