【JavaScript】JavaScriptまとめ④（関数）

# 概要
JavaScriptの理解を深めるため、
[<img width="200" alt="51vlB3JskRL.jpg" src="https://m.media-amazon.com/images/I/41vZUGXaYML._SX350_BO1,204,203,200_.jpg">](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E3%82%8F%E3%81%8B%E3%82%8BJavaScript-%E6%96%B0%E7%89%88-%E6%A1%9C%E5%BA%AD-%E6%B4%8B%E4%B9%8B/dp/4798173266/ref=sr_1_15?crid=341O9294X80Z7&keywords=javascript&qid=1679238835&sprefix=javas%2Caps%2C185&sr=8-15)
で学習した内容を記載していく。

本記事では、関数について記載する。

## 関数とは
`関数`とは、「処理をひとまとめにして名前をつけたもの」である。

関数は、インプットとして受け取った値を使って処理を行い、その処理結果をアウトプットできる。
プログラミングの世界では、このインプットのことを`引数`と呼び、アウトプットのことを`戻り値`と呼ぶ。

## 関数の書き方
関数を作ったタイミングでは、まだ中身の処理は実行されない。処理を実行させるには、関数を「作るコード」とは別に、「実行するコード」を記述する必要がある。関数を作ることを`関数を定義する`といい、関数に処理を実行させることを`関数を呼び出す`という。

### 関数宣言
#### 引数と戻り値が存在しない場合
関数宣言によって関数を定義するには、`function`キーワードに続いて`関数名()`のように書く。その後ろの`{}`で囲まれた範囲に、関数で実行する処理を書く。
```
function 関数名() {
    処理;
}
```
定義された関数を呼び出すには、`関数名()`のように書く。
```
関数名();
```
```function.js
// 関数を定義
function hello() {
    console.log('こんにちは');
}

hello(); // 関数を呼び出す
```
#### 引数が存在する場合
関数を定義する際の引数を`仮引数`という。
```
function 関数名(仮引数) {
    処理；
}
```
一方、関数を呼び出すときに実際に渡される引数を`実引数`と呼ぶ。
```
関数名(実引数);
```
引数でAliceを渡したら、`こんにちはAliceさん`と表示し、Bobを渡したら`こんにちはBobさん`と表示するようなプログラムを考える。
```function_with_argument.js
// 関数の定義 
function hello(name) {
    console.log(`こんにちは${name}さん`);
}

//　関数の呼び出し
hello('Alice');
hello('Bob');
```
#### 戻り値が存在する場合
戻り値を指定するには`return 戻り値`のように書く。
```
//　関数を定義する
function 関数名() {
    処理;
    return 戻り値;
}
```
例として、数字の3.14を返すだけの関数を作る。
```pi.js
function pi() {
    return 3.14;
}

const a = pi(); // 関数pi()を呼び出し、その戻り値を、変数aに代入している
console.log(a);
```
#### 引数と戻り値が存在する場合
「引数で受け取った数値の2倍を返す」関数は以下のように書くことができる。
```double.js
function double(number) {
    const result = number * 2;
    return result;
}

const a = double(10);
console.log(a);

const b = double(8);
console.log(b);
```
中身の処理では`number * 2`で引数の2倍を計算し、その結果を変数`result`に代入している。`return result`とすることで、計算結果を返すdouble関数完成する。

## 引数の応用
### デフォルト引数
```default_args1.js
function hello(name) {
    console.log(`こんにちは${name}さん`);
}

hello('Alice');
hello();
```
この関数Aliceという名前がわかっている場合は、`hello('Alice')`のように関数を呼び出し、求める処理を実行することができる。しかし、もしも人物名がわからない場合、例えば`hello()`のように引数を省略すると、`こんにちはundefinedさん`という文言が表示されてしまう。

#### デフォルト引数を使って改良してみよう
デフォルト引数を使うことで、上記の問題を改善することができる。
例えば、人物名がわからない場合は、`こんにちはundefinedさん`と表示するのではなく、`こんにちはゲストさん`と表示したいとする。その場合は以下のように書くことで実現することができる。
```default_args2.js
function hello(name = 'ゲスト') {
    console.log(`こんにちは${name}さん`);
}

hello();
```
ポイントは1行目の`name = 'ゲスト'`の部分。もしも関数を呼び出すときに実引数が渡されなかった場合は、=右辺の`ゲスト`という値が代わりに使われる。=右辺の値を`デフォルト値`と呼ぶ。このように、デフォルト値が設定された引数のことを`デフォルト引数`という。
```
function 関数名（仮引数 = デフォルト値） {
    処理;
}
```

## 関数式
### 関数式とは
関数式は関数宣言と異なり、文字通り関数を「式」として扱うことができる。

### 関数式の書き方
以下は、関数式を変数に代入する方法。
```
const 変数名 = function (引数1, 引数2, ・・・・・)　{
    処理;
    return 戻り値;
}
```
関数式と関数宣言の主な違いは、`function`キーワードの直後に関数名が存在しないこと。関数式はこのように名前のない関数を作ることができ、その関数は`無名関数`とも呼ばれる。
```function_expression.js
// 関数式を用いた関数定義
const sayHello = function() {
    console.log('こんにちは');
}

// 関数の呼び出し
sayHello();
```
上のコードは`sayHello`という変数に関数式を代入している。このように書くことで`sayHello`は関数と同じ振る舞いをすることになる。関数の呼び出しは関数宣言と同様に`sayHello()`と書く。

## スコープ
変数には有効範囲が存在する。ある変数を定義したときに、有効範囲を越えた場所では、その変数を使うことができない。この有効範囲のことを`スコープ`という。 

#### 関数スコープ
関数スコープとは関数を定義する際に作られるスコープである。
```scope.js
//　関数スコープ
function sample() {
    const x = 10;
    console.log(x); //　sample関数内部からxを参照することはできる
}
sample();
console.log(x); // sample関数外部からxは参照できないためエラーになる
```
#### ブロックスコープ
ブロック文によって作られるスコープをブロックスコープと呼ぶ。
```block_scope.js
if (true) {
    const x = 10;
    console.log(x); // ブロック内部から変数xを参照することはできる
}
console.log(x); //　ブロック外部から変数xは参照できないためエラーになる
```
#### グローバルスコープ
`グローバルスコープ`は入れ子構造の一番外側に常に存在しているスコープである。
グローバルスコープで宣言された変数を`グローバル変数`と呼ぶ。
```
const z = 1; //

function doSomething() {
    console.log(z); //　zを参照することができる
}

if (true) {
       console.log(z); //　zを参照することができる
}
```