# ES6 新功能
###### tags: `javascript`
ES6:ECMAScript 6
> doku wiki 支援的markdown so 糟糕,所以連結和圖片會跑掉....
## 參數預設值(Default Parameters) [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters "Default Parameters")
* 功能:在function接受參數時,可以給預設值,避免出現error。
* Example:
* 原本的寫法:
```javascript
function f ( pa, pb ) {
if ( pb === undefined )
pb = 10;
return pa + pb;
}
```
* 可以改寫成這樣:
```javascript
function f ( pa, pb = 10) {
return pa + pb;
}
```
## 變數宣告: `let` and `const`
* 功能:在ES6之前,變數選告只能使用`var`做宣告,[so糟糕](https://ithelp.ithome.com.tw/articles/10203548)。
* `let`:只會在目前的`{}`內有效,若重複定義會throw error。 [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let "let")
* `const`:一樣只會在目前的`{}`內有效,須給初始值,且值不可更改。 [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const "const")
* Example 1:
```javascript
function f ( ) {
let v = 1;
console.log ( v ); // output: 1
if ( true ) {
let v = "another instance";
console.log ( v ); // output: "another instance"
}
let v = 123;
// Uncaught SyntaxError: Identifier 'v' has already been declared
}
console.log( v );
// Uncaught ReferenceError: v is not defined
```
* Example 2:
```javascript
function f ( ) {
const newConst;
// Uncaught SyntaxError: Missing initializer in const declaration
const newConst2 = 0;
console.log ( newConst2 ); // output: 0
newConst2 = 2;
// Uncaught TypeError: Assignment to constant variable
}
console.log ( newConst2 );
// Uncaught ReferenceError: newConst2 is not defined
```
## 模板字串(Template Literals):`` `${}` `` [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals "Template Literals")
* 功能:
* 在ES6之前,要把多個變數和字串組在一起變成一個大字串只能用`+`來完成。現在可以在一行寫完。
* 在ES6之前,假如有一個字串有很多行,都需要在行尾加上`\`才會運作。現在可以不用管這件事了。
* 用法:
* 模板字串的頭尾使用反引號(`` ` ``)框起來,若中間有需要變數則使用`${}`並把變數放在`{}`裡面。
* 若有多行字串就照打下去就好了,不用管。
* Example 1:
* 原本的寫法:
```javascript
function f ( ) {
let i = "I";
let l = "hate";
let j = "JavaScript";
console.log ( i + " " + l + " " + j + "." );
// output: "I hate JavaScript."
}
```
* 可以改寫成這樣:
```javascript
function f ( pa, pb = 10) {
let i = "I";
let l = "hate";
let j = "JavaScript";
console.log ( `${i} ${l} ${j}` );
// output: "I hate JavaScript."
}
```
* Example 2:
* 原本的寫法:
```javascript
function f ( ) {
return (
"
A \
Multiple \
Line \
String \
"
);
}
```
* 可以改寫成這樣:
```javascript
function f ( ) {
return (
`
A
Multiple
Line
String
`
);
}
```
## Spread Operatpor and Rest Parameters:`...`
這兩個長得一模一樣都是由三個句號所組成:`...`。
* Spread Operator [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax "Spread Syntax") :
用來解構Array和Object,看例子比較快。
* Example 1: Array 的解構
```javascript
function f ( pa, pb, pc, pd ) {
console.log ( pa, pb, pc, pd );
}
let a = [1, 2, 3, 4];
f ( ...a ); // output: 1 2 3 4
// 可以看成是 f ( a[0], a[1], a[2], a[3] );
```
* Example 2: Array 的解構
```javascript
let arr1 = [1, 2]
let arr2 = [3, 4];
let result1 = [arr1, arr2];
let result2 = [...arr1, ...arr2];
console.log ( result1 ); // output: [[1, 2], [3, 4]]
console.log ( result2 ); // output: [1, 2, 3, 4]
```
* Example 3: Object 的解構
```javascript
let obj1 = {
a: 2,
b: 3
};
let obj2 = {
c: 3,
d: 4
}
let result1 = {obj1, obj2};
let result2 = {...obj1, ...obj2};
console.log ( result1 ); // output: {obj1: {a: 2, b: 3}, obj2: {c: 3, d: 4}}
console.log ( result2 ); // output: {a: 2, b: 3, c: 3, d: 4}
```
* Example 4: 用來object的key的預設值寫法,key重複會由最後面的決定其value(後面的會覆蓋前面的)。
```javascript
function f ( config ) {
const defualtConfig = {
configA: 1,
configB: "",
configC: null,
configD: "Some default value",
}
config = { ...defaultConfig, ...config };
// Some other codes here
}
```
* Rest Paramaters [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters "Rest Paramaters") :
如果 function 接受的參數數量不固定,可以使用 Rest Operator 把多個參數併成一個陣列。
_關於這個你也可以看看這個:[The arguments object
](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments "The arguments object
")_
* Example:
```javascript
function f ( pa, pb, ...r ) {
console.log ( r );
}
f ( 1, 2, 3, 4, 5, 6, 7 );
// output: [3, 4, 5, 6, 7]
```
## 解構賦值(Destructuring Assignment)[](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment "Destructuring Assignment")
ES6中從Array或Object取值的辦法,主要用`...`來完成。
* Example 1: Array
* 原本的寫法:
```javascript
let array = [1, 2, 3, 4];
let first = array [ 0 ];
let second = array [ 1 ];
let rest = array.slice(2);
console.log ( array ); // output: [1, 2, 3, 4]
console.log ( first ); // output: 1
console.log ( second ); // output: 2
console.log ( rest ); // output: [3, 4]
```
* ES6的寫法:
```javascript
let array = [1, 2, 3, 4];
let [first, second, ...rest] = array;
console.log ( array ); // output: [1, 2, 3, 4]
console.log ( first ); // output: 1
console.log ( second ); // output: 2
console.log ( rest ); // output: [3, 4]
```
* Example 2: Object
* 原本的寫法:
```javascript
let circle = {
border: "black",
fill: "white",
position_x: "2",
position_y: "3"
};
let border = circle.border;
let fill = circle.fill;
let radius = circle.radius || 1;
console.log ( border ); // output: "black"
console.log ( fill ); // output: "white"
console.log ( radius ); // output: 1
```
* ES6的寫法:
```javascript
let circle = {
border: "black",
fill: "white",
position_x: 2,
position_y: 3
};
let { border, fill, radius = 1 } = circle;
console.log ( border ); // output: "black"
console.log ( fill ); // output: "white"
console.log ( radius ); // output: 1
```
## 箭頭函式(Arrow Function)[](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions "Arrow Function")
* 箭頭函式主要用來取代舊版的匿名函示,`()=>{}`。
* 箭頭函式與原本的function的差別在於:
* 箭頭函式無法被`new`(為甚麼function可以被`new`?。
* 兩者的`this`指向不同(去看`this`那一篇的Lexical Binding。
* 新舊寫法對照:
* 舊版寫法:
```javascript
function ( /* put paramaters here, use comma to seperate them */ ) {
// some code here
return /* some return value here */;
}
```
* 新版寫法
```javascript
( /* put paramaters here, use comma to seperate */ ) => {
// some code here
return /* some return value here */;
}
```
* 如果參數只有一個,則小括弧(`()`)可以省略。
* 如果後面的內容直接是回傳值,則大括弧(`{}`)和`return`可以省略。
* Example 1:
* 舊版寫法:
```javascript
let words = ['concat', 'filter', 'entries', 'findIndex', 'lastIndexOf', 'reduceRight', 'undefined', 'toLowerCase'];
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
let results = words.filter ( function ( w ) {
if ( w.length > 10 )
return true;
else
return false;
} );
console.log ( results ); // output: ["lastIndexOf", "reduceRight", "toLowerCase"]
```
* 第一次改寫:先改寫成arrow function 的寫法
```javascript
let results = words.filter ( ( w ) => {
if ( w.length > 10 )
return true;
else
return false;
} );
```
* 第二次改寫:因為參數只有一個,所以小括弧拿掉
```javascript
let results = words.filter ( w => {
if ( w.length > 10 )
return true;
else
return false;
} );
```
* 第三次改寫:改寫`return`的部分
```javascript
let results = words.filter ( w => {
return w.length > 10;
} );
```
* 最後改寫:因為內容的部分直接是`return`的部分,所以把大括弧和`return`拿掉。
```javascript
let results = words.filter ( w => w.length > 10 );
```
* Example 2: 下面兩行code結果完全相同。
```javascript
let l = length.reduce( ( a, c ) => lcm ( a, c ), 1 );
let l = length.reduce( lcm, 1 );
```
* Example 3: 來解讀看看吧
```javascript
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
let func = arr => arr.filter ( ( e, i, a ) => a.indexOf ( e ) === i );
let array = [2, 3, 18, 5, 9, 0, 10, 5, 10, 3, 7, 9, 18];
let results = func ( array );
console.log ( results ); // output ?
```
## `Class` [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes "Classes")
ES6 開始支援`Class`。寫類別的時候更直覺也可以繼承。
* Example:
```javascript
// 使用extends關鍵字來繼承其他的類別
Class Car extends Vehicle{
// constructor 是保留字,這個function就是建構式,類別剛建立的時候會做的事情。
constructor ( ) {
// 使用super來call父類別的建構子
super ( );
}
// 一般的function
f ( ) {
// some codes here
return /* some return value */;
}
// 一個static function
static f2 () {
}
}
```
## `Promise` [](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises "Using promises")
就非同步嘛~有空再縮。
## 參考資料
* JavaScript (ES6) Syntax 大集合:https://ithelp.ithome.com.tw/articles/10191712
* 淺談JS版本差異!ES5、ES6:https://ithelp.ithome.com.tw/articles/10206587
* [ES6] Javascript 開發者必須知道的 10 個新功能:https://medium.com/@peterchang_82818/es6-10-features-javascript-developer-must-know-98b9782bef44