【JavaScript】アロー関数について調べてみた

## 概要
アロー関数とはES2015（ES6）から利用可能となった、
無名関数をより短く書く事のできる記法です。

ただ、アロー関数を使用した場合、thisの扱いが変わるので使用する場合は特性を理解して使う必要があります。

最近、アロー関数を使う機会が増えてきているので、
復習の為にまとめました。

ES2015以降の記法なのでレガシーブラウザに対応させる場合は、トランスパイラ（Babel等）を使用し、ES5記法にトランスパイルをおこなってください。
[Babelとは？](https://qiita.com/hietahappousai/items/9570da4b9275425489b2#babel%E3%81%A8%E3%81%AF)

アロー関数を使用する、メリットは以下の2つです。
・無名関数を短い記述で書くことができる
・thisをレキシカル（構文的）に使う事ができる

## 無名関数を短くかける

例えば

```js
// functionの場合
const functionHalfNumber = function(number) {
    return number / 2;
}
functionHalfNumber(4);


// アロー関数の場合
const arrowHalfNumber = number => number / 2;
arrowHalfNumber(4);
```

上記のコードのように省略する事ができます。
ポイントは3つです。

### functionの代わりに=>で書ける

```js
// functionを使う場合
const functionHalfNumber = function(number) {
    return number / 2;
}
console.log(functionHalfNumber(4)); //2

// アロー関数の場合
const arrowHalfNumber = (number) => {
    return number / 2
}
console.log(arrowHalfNumber(4)); //2
```
アロー関数の場合、functionではなく、
引数の後に=>と記述する事で無名関数を宣言する事ができます。

### {}とreturnを省略できる
評価項目が一つで、一行に記述する場合はreturnと{}を省略できます。
※省略するかしないかは任意です。

```js
// functionを使う場合
const functionHalfNumber = function(number) {
    return number / 2;
}
console.log(functionHalfNumber(4)); //2

// アロー関数の場合
const arrowHalfNumber = (number) => number / 2

console.log(arrowHalfNumber(4)); //2
```

ただし、オブジェクトリテラルを返却する場合は、()で囲ってあげる必要があります。

```js
// functionを使う場合
const functionHalfNumber = function(number) {
    return {value: number / 2};
}
console.log(functionHalfNumber(4)); // {value: 2}


// アロー関数の場合
const arrowHalfNumber = number => ({value: number / 2});
console.log(arrowHalfNumber(4)); //{value: 2}
```

### 引数の()を省略できる ※引数が一個の場合
引数が一つの場合、()を省略する事ができます。

```js
// functionを使う場合
const functionHalfNumber = function(number) {
    return number / 2;
}
console.log(functionHalfNumber(4)); //2

// アロー関数の場合
const arrowHalfNumber = number => number / 2

console.log(arrowHalfNumber(4)); //2

```

## thisをレキシカル（構文的）にできる
functionを使用して関数を宣言すると、thisの参照先は、
その関数を呼び出したオブジェクト（レシーバオブジェクト）になります。

例えば

```js
function studentSummary(){
    console.log(`${this.name}は${this.highSchoolName}の生徒です。`);
} //  一郎はA高校の生徒です。 次郎はB高校の生徒です。

const student01 = {
    name: '一郎',
    highSchoolName: 'A高校',
    studentSummary: studentSummary
}

const student02 = {
    name: '次郎',
    highSchoolName: 'B高校',
    studentSummary: studentSummary
}

student01.studentSummary();
student02.studentSummary();
```
このようにthisは、呼び出したオブジェクト（レシーバオブジェクト）を参照します。
ポイントとしては**関数を定義した時点ではthisはどのオブジェクトを参照するのか決まっていない**という事です。
呼び出し元によってthisの値を変化させたい場合はアロー関数を使用せずfunctionを使用します。

アロー関数が便利なシーンはこんな時です。
例えば、

```js
const student = {
    name: '一郎',
    highSchoolName: 'A高校',
    studentSummary: function() {
        return `${this.name}は${this.highSchoolName}の生徒です。`;
    }
}

console.log(student.studentSummary()); //一郎はA高校の生徒です。
```

この場合は`studentSummary`を呼び出しているのは`student`オブジェクトなので問題なくプロパティを参照できます。

この場合はどうでしょう?
map関数のコールバック関数内でthisを使ってみます。

```js
const student = {
    names: ['一郎', '次郎'],
    highSchoolName: 'A高校',
    studentSummary: function() {
        return this.names.map(function(name) {
            return `${name}は${this.highSchoolName}の生徒です。`
        })
    }
}

console.log(student.studentSummary()); // [ '一郎はundefinedの生徒です。', '次郎はundefinedの生徒です。' ]
```

undefinedとなってしまいました。
関数が関数を呼び出すとthisはグローバルオブジェクトを参照してしまうのです。

このような場合にアロー関数が役に立ちます。

```js
const student = {
    names: ['一郎', '次郎'],
    highSchoolName: 'A高校',
    studentSummary: function() {
        return this.names.map(name => {
            return `${name}は${this.highSchoolName}の生徒です。`
        })
    }
}

console.log(student.studentSummary()); //  [ '一郎はA高校の生徒です。', '次郎はA高校の生徒です。' ]
```

無事、高校名を取得する事が出来ました。
アロー関数は宣言された時点で**thisがどのオブジェクトを参照するか確定させる事**ができます。

このケース（関数が関数を呼び出す）の場合は所属しているオブジェクトです。

## まとめ
**【無名関数を短い記述で書くことができる】**
・functionの代わりに=>で書ける
・{}とreturnを省略できる
・引数の()を省略できる ※引数が一個の場合

**【thisをレキシカル（構文的）に使う事ができる】**
・呼び出されたオブジェクトによってthisの参照先を変えたいときはfunctionを使う
・宣言した時点でどのオブジェクトを参照するか確定させたい時はアロー関数を使う