# 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) :::