# ES6 的一些常用新語法 ###### tags: `JavaScript` `ES6` ## var, let, const ### var 宣告變數(ES5) > var 宣告變數時,它的作用範圍可以是全域也可以是區域,但如果使用區塊語句(ex: if, else, for, while)時,宣告的區域變數仍然可在作用範圍外被存取 #### 情境一 > var 一個全域變數可在 function 內/外使用、可被存取與修改 ``` var i = 3; (function () { i += 1; })(); console.log(i); // 輸出結果為 4 ``` #### 情境二 > var 一個區域變數執行結束後就會失效,故在 function 外取 *j* 的值是 undefined ``` (function () { var j = 4; j += 1; })(); console.log(j); // 輸出結果為 j is not defined ``` #### 情境三(宣告與不宣告) > 若無宣告,則其變數會被當成全域變數 ``` (function x() { y = 1; // 無宣告,因此被作為全域變數使用 var z = 2; })(); console.log(y); // 為全域變數,所以 y = 1 console.log(z); // 為區域變數,所以 z 未被找到 ``` ### let 變數宣告(ES6) > let 可以只宣告在目前作用的區塊、階段或表達式中作用的變數 #### 範例 ``` let x = 1; if (x === 1) { let x = 2; console.log(x); // 會輸出 2 } console.log(x); // 會輸出 1 ``` ### let 與 var 差異比較 #### 情境一 (在 if 中分別使用 var 與 let 宣告) * var ( if 跑完後,在區塊語句外可以輸出 *b* ) ``` if (true) { var b = 20; } console.log(b); // 輸出值為 20 ``` * let ( if 跑完後,在區塊語句外無法輸出 *b* ) ``` if (true) { let b = 20; } console.log(b); // 會輸出 b is not defined ``` #### 情境二(在 function 區塊與子區塊中宣告) * var ``` (function varTest() { var x = 1; { var x = 2; // 這裡的x是一樣的,會改變整個 function 的 x console.log(x); // 輸出值為 2 } console.log(x); // 輸出值為 2 })(); ``` * let ``` (function letTest() { let x = 1; { let x = 2; // 這裡的 x 是不同的,只會作用在這層區塊中 console.log(x); // 輸出 2 } console.log(x); // 輸出 1 })(); ``` ### const(ES6) const 會對於它的值建立一個唯讀的參考( const 宣告時一定要有值,否則會跳錯誤)。並不是說這個值不可變更,而是這個變數不能重新指定值,例如常數的內容(值)是個物件,那麼此物件的參數是可以更改的。它與 let 一樣都是可以只宣告在目前作用的區塊 #### 情境一(宣告一個常數) ``` const firstName = 'HSU'; // 測試 1 firstName = 'LIN'; //Error: firstName 已經分配給常數 // 測試 2 const firstName = 'LIN'; //Error: firstName 已經被宣告過 // 測試 3 let firstName = 'LIN'; //Error: firstName 已被宣告 ``` #### 情境二(宣告常數為一個物件) ``` const room = [{ teacher: 'Lin', students: 30 }, { teacher: 'Wang', students: 36 } ] room[0].teacher = 'Chen'; console.log(room[0].teacher); //會輸出 Chen ``` ## Arrow Functions(箭頭函式) > 讓匿名函式寫法更簡略,寫法為 `( ) => { }` ,如果只有一行語句的話可以省略大括號,它會自動 `return` ,但也只能在只有一行語句的時候使用。 > 使用大括號 `{ }` 則是可以加入多行的語句,不過不會自動 `return` ,有需要的話要自己加上,如果沒加 `return` 的話,之後執行會輸出 undefined。 ### JavaScript(ES5) ``` var count = function(a, b){ return a * b; } count(2, 5); ``` ### JavaScript(ES6) #### 情境一(只有一個參數) > 當函數只有一個參數時,不需要使用括號 ``` // 原 let count = (a) => { return a + 1; }; // 可寫成 let count = a => a + 1; count(5); // 會輸出 6 ``` #### 情境二(兩個以上的參數) ``` let count = (a, b) => a * b; count(2, 6); // 會輸出 12 ``` ## Template Literals(模板文字) > 在 String 內嵌入變數時,在 ES5 中必須把字串拆散,通過" + "字元加入字串; 而在 ES6 中,變數被容許通過語法 ${value} 加在字串中,但是需被" ` " (反引號)包在裡面而不是單/雙引號 ### Expression interpolation #### JavaScript(ES5) ``` var a = 5; console.log('Five is ' + a + '.'); ``` #### JavaScript(ES6) ``` let a = 5; console.log(`Five is ${a} .`); ``` ### Multi-line Strings(多行字串符) #### JavaScript(ES5) > ES5 中,若字串要換行需加 \n ``` let str="line1"; let str2="line2"; console.log( str+'\n' + str2); ``` #### JavaScript(ES6) > ES6 中,只要用反引號包起來,再根據要換行的地方做換行動作就好 ``` let str="line1"; let str2="line2"; console.log(`str str2`); ``` 參考來源: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const https://wcc723.github.io/javascript/2017/12/21/javascript-es6-arrow-function/