---
# System prepended metadata

title: ES6 的一些常用新語法
tags: [ES6, JavaScript]

---

# 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/