Javascriptにおける関数について

学習で学んだことを自分なりに整理してみました。間違っている部分や追記した方が良いなどアドバイスがあれば教えていただけたら幸いです。

---

## 関数とは
- **入力**…関数の引数
- **処理**…関数の実行内容
- **出力**…関数の実行結果

### 関数の必要性

- 関数を作らずにコードを書いた場合、コード量が多くなれば多くなるほど管理が難しくなり、バグなどの発見に時間がかかってしまう。
そこで１つの機能ごとに関数を作ることでコードを見やすく、管理を簡単にすることができる。また、ブロック式でスコープを限定することで影響反映を操作することができる。


- プログラミングでは「DRY(Don't Repeat Yourself)」という考えがある。同じ処理のコードを何度も繰り返し記述していくと構造が見辛くなる。また、コピペして書いていた場合、その最初にコピーしたコードの内容が間違っていたら全てを修正する必要がある。
１つの処理を関数で作ることにより、コードの修正も容易にすることができる。

---

## 関数の作り方

### 関数宣言

#### functionキーワードを使う

```js
function 関数名(){
// ここに処理を入力
}
```

関数宣言の場合は、宣言されているコードより前に記述しても実行される。これは **関数の巻き上げ(ホイスティング)** と呼ばれる。

例

```js
world('hello') //実行できる、実行結果:hello world

function world(test){
  console.log(test, 'world');
}

world('goodnight') //実行できる、実行結果:goodnight world
```



#### 即時関数

使用することでスコープを切った変数を作ることができる

```js
(function(a,b){
  console.log(a + b)
})(1,2); // 実行結果:3
```

現状`let`や`const`があるので使う機会があるかどうかは微妙？

### 関数式

変数に関数を代入する書き方。
先頭に変数を置き、変数に保存する値として関数を定義する。

```js
const 変数名 = function(){
//ここに処理を入力
};
```

関数式ではfunctionの後に関数名を記述しないのが一般的で、このような関数名の無い関数のことを **無名関数** と呼ぶ

また、関数式の場合は、関数宣言ではなく変数宣言であるため、宣言する前に記述しても実行することができない

例

```js
hello() //実行できずエラーになる

const hello = function(){
  console.log('hello');
}

hello() //実行可能、実行結果:hello
```

### アロー関数

ES2015(ECMAScript2015)から追加された新しい関数の書き方。
先頭に変数を置き、保存する値としてアロー関数を定義する。

```js
const 変数名 = () =>{
// ここに処理を入力
}
```
引数が１個だけの時は`()`を省略してかけるが、0もしくは２個以上の場合は`()`が必須。

```js
const hello = test => {
  console.log(test,'world');
};

hello('hello');

// 出力結果: hello world
```

関数内の処理が値を返すだけなら、ブロック(`{}`)ではなく式を書くことができる。式の値が戻り値となるため`return`文は書かない。

```js
const test = x => x + 1;
```

#### thisの挙動の違い

Javascriptでは、`function`を使っているか、`アロー`を使っているかによって関数内の`this`の挙動が変わることがある。まだ習っていない部分なので詳しくはまた今度


#### 関数名をつける際のルール

- １単語しか使わない場合は小文字だけで記述する
- ２単語以上の場合は **２単語目以降の各単語の先頭１文字目を大文字にして** それ以外は小文字にする(ローワーキャメルケース)
- 複数の単語を「アンダースコア(_)」で繋げる書き方もある(スネークケース)
- ２単語以上の場合は「動詞」+「名詞（目的語）」で記述する。

変数名をつける際参考になるサイト
[うまくメソッド名を付けるための参考情報(Qiita)](https://qiita.com/KeithYokoma/items/2193cf79ba76563e3db6)


---

## 引数

関数実行時に関数に渡す数のこと。
`()`の中に引数を入力する。どのやり方でも引数の入力の仕方は変わらない。

### 入力方法

#### 関数宣言の場合
```js
function hello(name,age){
  console.log('こんにちは、' + name + '(' + age + '歳)さん');
}

hello('じん', 24);

// 実行結果こんにちは、じん(24歳)さん
```


#### 関数式の場合
```js
const hello =function(name,age){
  console.log('こんにちは、' + name + '(' + age + '歳)さん');
}

hello('じん', 24);

// 実行結果こんにちは、じん(24歳)さん
```


#### アロー関数の場合
```js
const hello = (name,age) => {
  console.log('こんにちは、' + name + '(' + age + '歳)さん');
}

hello('じん', 24);

// 実行結果こんにちは、じん(24歳)さん
```

---

## 戻り値（返り値）

関数の実行結果を関数の呼び出し元に返す値のこと。
関数の末尾に`return`キーワードを使う

### 使用方法

```js
const add = (a,b) =>{
  return a + b; // a + bの計算結果が呼び出し元に返る
}

const result1 = add(1, 2); // add内で計算された結果'3'がaddに返され、result1変数に代入される
console.log(result1);// 実行結果 3


const sub = (a,b) =>{
  const result = a - b;
  return result; // a - bの実行結果が呼び出し元に返る
}

const result2 = sub(5, 1); // sub内で計算された結果'4'がsubに返され、result2変数に代入される
console.log(result2); // 実行結果 4

console.log(sub(3,5)) // 別の関数の戻り値を直接セットすることもできる 実行結果 -2
```


また、`return`キーワードを使わず関数を実行した場合、値が返されることがないので **`undefined`(値が定義されていない)** となる

例

```js
const add = (a,b) =>{
  a + b; // 関数内で実行されているだけで、どこにも返されていない
}

const result1 = add(1,2); // 引数を渡しても返されることがない
console.log(result1) // 実行結果 undefined
```

しかし、アロー関数で式を書いた場合は、前述のように式の値が文が戻り値になるので、`return`キーワードを使わない。