この記事でアロー関数をすぐに理解できる



#### 基本構文

アロー関数の基本構文は次の通りです：

```javascript
(param1, param2, ..., paramN) => { statements }
```

もし引数が1つだけの場合、丸括弧を省略できます：

```javascript
param => { statements }
```

関数本体が1つの式のみで、その式が返り値を必要とする場合は、大括弧と `return` キーワードを省略できます：

```javascript
(param1, param2, ..., paramN) => expression
```

### 例

#### 1. 引数がないアロー関数

**アロー関数：**

```javascript
const sayHello = () => {
    console.log("Hello, world!");
};
sayHello(); // 出力：Hello, world!
```

**従来の関数式：**

```javascript
const sayHello = function() {
    console.log("Hello, world!");
};
sayHello(); // 出力：Hello, world!
```

#### 2. 引数が1つのアロー関数

**アロー関数：**

```javascript
const square = x => {
    return x * x;
};
console.log(square(5)); // 出力：25
```

**従来の関数式：**

```javascript
const square = function(x) {
    return x * x;
};
console.log(square(5)); // 出力：25
```

#### 3. 短縮記法のアロー関数（暗黙の返り値）

**アロー関数：**

```javascript
const add = (a, b) => a + b;
console.log(add(2, 3)); // 出力：5
```

**従来の関数式：**

```javascript
const add = function(a, b) {
    return a + b;
};
console.log(add(2, 3)); // 出力：5
```

### 従来の関数との違い

#### 1. `this` バインディング

**従来の関数内の `this`**

従来の関数では、`this` は関数の呼び出し方によって決まります。以下の例では、`this` はグローバルオブジェクト（ブラウザでは `window`）を指します：

```javascript
function showValue() {
    this.value = 10;
    setTimeout(function() {
        console.log(this.value); // `this` はグローバルオブジェクトを指す
    }, 1000);
}

showValue(); // 出力：undefined、グローバルオブジェクト上に `value` がないため
```

- `setTimeout` 内の従来の関数では、`this` は `showValue` 関数の `this` ではなく、グローバルオブジェクト（ブラウザでは `window`）を指します。
- グローバルオブジェクト上には `value` プロパティがないため、出力は `undefined` です。

**アロー関数内の `this`**

アロー関数は独自の `this` を持たず、外部のコンテキスト内の `this` をキャプチャします。以下は同じ例をアロー関数で書いたものです：

```javascript
function showValue() {
    this.value = 10;
    setTimeout(() => {
        console.log(this.value); // `this` は外部関数の `this` を指す
    }, 1000);
}

const obj = new showValue(); // 出力：10
```

- `setTimeout` 内のアロー関数では、`this` は `showValue` 関数内の `this` を指し、`showValue` インスタンスの `this` になります。
- そのため、`this.value` は `10` で、出力は `10` です。

#### 2. コンストラクタ関数として使えない

**従来の関数をコンストラクタ関数として使用する**

従来の関数では、`new` キーワードを使ってオブジェクトインスタンスを作成できます。例えば：

```javascript
// 従来のコンストラクタ関数
function Person(name) {
    this.name = name;
}

const john = new Person('John');
console.log(john.name); // 出力：John
```

- この例では、`Person` はコンストラクタ関数で、`new Person('John')` によって新しい `Person` インスタンスが作成され、`name` プロパティが `'John'` に設定されます。

**アロー関数はコンストラクタ関数として使えない**

アロー関数はコンストラクタ関数として使用できません。アロー関数を `new` キーワードで呼び出そうとすると、エラーが発生します。例えば：

```javascript
// アロー関数
const Person = (name) => {
    this.name = name;
};

// アロー関数をコンストラクタ関数として使おうとする
try {
    const john = new Person('John'); // TypeError: Person is not a constructor
} catch (e) {
    console.error(e.message); // 出力：Person is not a constructor
}
```

- この例では、`Person` はアロー関数です。`new Person('John')` でオブジェクトを作成しようとすると、`TypeError` がスローされます。これは、アロー関数には独自の `this` がなく、コンストラクタ関数の機能がないためです。

#### 3. `arguments` オブジェクトがない

**従来の関数内の `arguments`**

従来の関数では、`arguments` オブジェクトを使って関数に渡されたすべての引数にアクセスできます：

```javascript
function showArguments() {
    console.log(arguments);
}

showArguments(1, 2, 3, 4); // 出力：{ '0': 1, '1': 2, '2': 3, '3': 4 }
```

- `arguments` オブジェクトは配列に似たオブジェクトで、インデックスを使って引数にアクセスしたり、`length` プロパティで引数の数を取得したりできます。

**アロー関数内の `arguments`**

アロー関数には独自の `arguments` オブジェクトがありません。アロー関数に渡された引数にアクセスするには、`rest` パラメータ構文を使うことができます。

```javascript
const showArguments = (...args) => {
    console.log(args);
};

showArguments(1, 2, 3, 4); // 出力：[1, 2, 3, 4]
```

- `...args`（rest パラメータ）を使うことで、関数に渡されたすべての引数を配列 `args` に収集できます。
- `rest` パラメータは関数のパラメータリストの最後に置く必要があり、任意の数の引数を受け取ることができます。

### まとめ

アロー関数は、特に短いコールバック関数や独自の `this` バインディングが不要なシーンに適した簡潔な関数定義方法を提供します。ただし、コンストラクタ関数が必要な場合や、`this` バインディングや `arguments` オブジェクトを使う必要がある場合は、従来の関数式の方が適しています。