ES6の記法（テンプレートリテラル、アロー関数、オブジェクトリテラル、デフォルト引数、RestとSpread演算子、分割代入、クラス）

# テンプレートリテラル

```javascript
function doubleMessage(number) {
  return `${number}を2倍すると${2 * number}になります`;
}
```

```javascript
function fullName(firstName, lastName) {
  return `${firstName} ${lastName}`;
}
```

# アロー関数

```javascript
const fibonacci = n => {
  if (n < 3) return 1;
  return fibonacci(n - 1) + fibonacci(n - 2);
}
```

```javascript
const profile = {
    name: '太郎',
    getName: function() {
        return this.name;
    }
};
```
# オブジェクトリテラル

```javascript
const red = '#ff0000';
const blue = '#0000ff';
const COLORS = { red, blue };
```

```javascript
const fields = ['firstName', 'lastName', 'phoneNumber'];   
const props = { fields };
```

```javascript
const canvasDimensions = (width, initialHeight) => {
  const height = initialHeight * 9 /16;
  return { width, height };
}
```

```javascript
const color = 'red';
const Car = {
  color,
  drive() { return 'ブーーン!'; },
  getColor() { return this.color; }
};
```

# デフォルト引数
```javascript
function sum(a=0, b=0) {
  return a + b;
}
```

```javascript
function addOffset(style={}) {
  style.offset = '10px';
  return style;
}
```

# RestとSpread演算子
## Rest演算子
引数のところで(...rest)という形で、可変長引数を実現する。
restは関数の中で配列になる。

##Spread演算子
...arrayの形で配列を展開できる。

```javascript
function validateShoppingList(...items) {
    if(items.indexOf('牛乳') < 0) {
        return ['牛乳', ...items];
    }
    return items;
}
```

```javascript
function product(...rest) {
  var numbers = [...rest];
  return numbers.reduce(function(acc, number) {
    return acc * number;
  }, 1)
}
```

```javascript
function join(array1, array2) {
  return [...array1, ...array2];
}
```

```javascript
function unshift(array, ...rest) {
  return [...rest, ...array];
}
```
# 分割代入
```javascript
const savedFile = {
    extension: 'jpg',
    name: 'profile',
    size: 14040
}

function fileSummary({ name, extension, size}) {
    return `${name}.${extension}の容量は${size}です。`;
}
```

```javascript
const companies = [
    'Google',
    'Facebook',
    'Uber'
];

const [name, ...rest]  = companies;
```

```javascript
const companies = [
    {name: 'Google', location: 'マウンテンビュー'},
    {name: 'Facebook', location: 'メンロパーク'},
    {name: 'Uber', location: 'サンフランシスコ'}
];

const [ {location} ] = companies;
```

```javascript
const Google = {
    locations: ['マウンテンビュー', 'ニューヨーク', 'ロンドン']
};

const { locations: [ first ]} = Google;
```

```javascript
const points = [
    [4, 5],
    [10, 1],
    [0, 40]
];

// points.map(point => {
//     const x = point[0];
//     const y = point[1];
//     return {x: x, y: y};
// });

// points.map(point => {
//     const [x, y] = point;
//     return {x, y};
// });

points.map(([x, y]) => {
    return {x, y};
});
```

```javascript
const profile = {
  title: 'エンジニア',
  department: '開発部'
};
function isEngineer(profile) {
//   var title = profile.title;
//   var department = profile.department;
  const {title, department} = profile;
  return title === 'エンジニア' && department === '開発部';
}
```

```javascript
const classes = [
  [ '化学', '1時限目', '鈴木先生' ],
  [ '物理', '2時限目', '佐藤先生'],
  [ '数学', '3時限目', '木村先生' ]
];
const classesAsObject = classes.map(([subject, time, teacher])=> {
    return {subject, time, teacher};
});
```

```javascript
const numbers = [1,2,3];
 
function double([ head, ...rest ]) {
  if (!head) { return []; }
  return [ 2 * head, ...double(rest) ];
}
```

# クラス
```javascript
class MyStorage  {
    constructor(app) {
        this.app = app;
        this.storage = localStorage;
        this.data = JSON.parse(this.storage[this.app] || '{}');
    }

    getItem(key) {
        return this.data[key];
    }

    setItem(key, value) {
        this.data[key] = value;
    };

    save() {
        this.storage[this.app] = JSON.stringify(this.data);
    };
}

const storage = new MyStorage('JSSample');
storage.setItem('fuga', 'ふが');
console.log(storage.getItem('fuga'));
storage.save();
```
```javascript
class Monster {
  constructor(options) {
    this.health = 100;
    this.name = options.name;
  }
}

class Snake extends Monster {
    constructor(options) {
        super(options);
    }
    
    bite(other) {
        other.health -= 10;
    }
}
```
# Promise
```javascript
function asyncProcess(value) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (value) {
                resolve(`入力値: ${value}`);
            } else {
                reject('入力は空です');
            }
        }, 500);
    });
}

asyncProcess('トクジロウ').then(
    response => {
        console.log(response);
        return asyncProcess('ニンサブロウ');
    }
).then (
    response => {
        console.log(response);
    },
    error => {
        console.error(`エラー: ${error}`);
    }
);
```

Promise.allメソッドで複数の非同期処理を並列に実行し、その全てが成功した場合に処理を実行する。

```javascript
Promise.all([
    asyncProcess('トクジロウ'),
    asyncProcess('ニンサブロウ'),
    asyncProcess('リンリン'),
]).then(
    response => {
        console.log(response);
    },
    error => {
        console.error(`エラー: ${error}`);
    }
)
```