関数とは[JavaScript本格入門]__WebデザイナーのJS学習備忘録

# はじめに

Qiita3回目の投稿になります。今回は学習のJavaScriptの基本構文「関数とは」についてまとめていきます。

JavaScriptの人気書籍**「JavaScript本格入門」**を学習教材として使用しているのですが、かなり分厚い書籍で持ち歩くのも不便なのでいつでも見れるように内容を凝縮してQiitaに投稿して共有できればと思い、投稿することにしました。

※ この記事の内容は基本的な関数の構文に関する説明のため、私と同じように**JavaScript入門者**に向けての記事となります。

#関数とは

与えられたパラメーター（引数）に基づいてあらかじめ決められた処理を行い、その処理の結果を返す仕組みを関数という。
JSではデフォルトで多くの関数を提供しているが、自分で関数を定義することもできる。自分で定義した関数のことをデフォルトの関数と区別して**ユーザー定義関数**という。

ユーザー定義関数を定義するには、4つの方法がある。
<font color="skyblue">
1. function命令で定義する
2. Functionコンストラクター経由で定義する
3. 関数リテラル表現で定義する
4. アロー関数で定義する
</span>

## function命令で定義する

● function命令 - 構文 -

```script.js
function 関数名（引数, ...) {
  実行する処理
  return 戻り値;
}
```

**関数名を付ける時の注意点**

- （単なる文字列ではなく）識別子の条件を満たす必要がある
- 「その関数がどのような処理を実行するのか」すぐ把握できる名前を付ける

→「動詞＋名詞」の形式で命名するのが一般的
→camelCase形式
名前の先頭が小文字、単語の区切りを大文字で表す記法のことで関数名は**camelCase記法**で表すのが基本


### 引数
引数は関数の挙動を決めるためのパラメーターである。
呼び出し元から指定された値を受け取るための変数を、カンマ区切りで指定する。
仮引数ともいい、関数内部でのみ参照できる。

### 戻り値（返り値）
関数が処理の結果、最終的に呼び出し元に返すための値のことである。
通常、関数の末尾にreturn命令を記述して指定する。
関数の途中でreturn命令を記述したら、それ以降の処理は実行されない。

戻り値がない（返す値がない）- 呼び出し元に値を返さない関数では、return命令を省略しても構わない。
return命令が省略された場合、関数はデフォルトで**undefined（未定義）**を返す。


#### 関数の定義

▼ サンプルコード

```script.js
function getTriangle(base, height) {
  return base * height / 2;
}

console.log("三角形の面積:" getTriangle(5,2));    //結果：5
```

#### 定義済みの関数を呼び出す方法

```script.js
関数名([引数,...]);
```

関数定義で宣言された引数（仮引数）と区別する意味で、呼び出し側の引数を実引数という。

**関数の注意点**

- 関数の後方の丸カッコ（）は省略できない。
- 丸カッコを省略した場合、関数の定義内容がそのまま出力されてしまう。


## Functionコンストラクター経由で定義する

JavaScriptには組み込みオブジェクトとしてFunctionオブジェクトを用意しており、関数はこのFunctionオブジェクトのコンストラクターを利用して定義することもできる。

● Functionコンストラクター - 構文 -

```script.js
var 変数名 = new Function(引数,... , 関数の本体);
```

▼ サンプルコード

```script.js
var getTriangle = new Function('base','height', 'return base * height / 2');
console.log("三角形の面積:" + getTriangle(5,2));    //結果：5
```

Functionコンストラクターには、関数が受け取る仮引数を順に並べ、最後に関数の本体を指定するのが基本

**Functionコンストラクターには省略する記述方法がある**

new演算子を省略してあたかもグローバル関数であるかのように記述することもできる

```script.js
var getTriangle = Function('base','height','return base * height / 2');
```
<br>
仮引数の部分を1つの引数として記述することもできる

```script.js
var getTriangle = new Function('base, height', 'return base * height / 2');
```

### Functionコンストラクターを使用するメリット
実は、特別な理由がない限り、あえてFunctionコンストラクターを利用するメリットはない。

だが、Functionコンストラクターはfunction命令にはない重要な特徴として「Functionコンストラクターでは、引数や関数本体を文字列として定義できる」という点がある。

▼ サンプルコード

```script.js
var param = 'height, width';
var formula = 'return height * width / 2';
var diamond = new Function(param, formula);
console.log("菱形の面積:" + diamond(5,2));
```

**上記の記述方法の注意点**
外部からの入力によって関数によって関数を生成した場合には、外部から任意のコードを実行できてしまう可能性がある。
Functionコンストラクターは実行時に呼び出されるたびに、コードの解析から関数オブジェクトの生成までを実行するため、実行パフォーマンス低下に影響する可能性がある。

特に以下の箇所で使用することは避けるべき。

<font color="skyblue">
- while/for文などの繰り返しブロックの中
- 頻繁に呼び出される関数の中
</font>

**重要ポイント！**
JavaScriptの関数は、原則として**function命令、関数リテラル、アロー関数**で定義する。


## 関数リテラル表現で定義する

JavaScriptにおいて関数はデータ型の一種であり、文字列や数値と同じく**リテラルとして表現できるし、関数リテラルを変数に代入したり、ある関数の引数として渡したり、戻り値として関数を返すこともできる。**

※リテラルとは、プログラム上で数値や文字列など、データ型の値を書ける構文として定義したもの。

▼ サンプルコード

```script.js
var getTriangle = function(base, height) {
  return base * height / 2;
};
console.log('三角形の面積:' + getTriangle(5,2));    //結果：5
```

**function命令と関数リテラルの違い**

**function命令** → 関数getTriangleを直接定義している。
**関数リテラル** → 「function(base, height){...}」と名前のない関数を定義した上で、変数getTriangleに格納している。

関数リテラルは宣言した時点で、名前を持たないことから**匿名関数**または、**無名関数**と呼ばれることもある。

## アロー関数で定義する
アロー関数は**ES6(ES2015)**で新たに追加された記法で、関数リテラルをよりシンプルに記述できる。

●　アロー関数 - 構文 - 

```
(引数,...) => {...関数の本体...}
```

▼ サンプルコード

```script.js
let getTriangle = (base, height) => {
  return base * height / 2;
};

console.log('三角形の面積:' + getTriangle(5,2));    //結果：5
```

アロー関数では、functionを書かず、代わりに=>で引数と関数本体をつなぐ。

アロー関数はこの他にコードをシンプルに記述する方法がある。

本体が一文である場合には、ブロックを表す{...}を省略できる
文の戻り値がそのまま戻り値と見なされるので、return命令も省略可能。

```script.js
let getTriangle = (base, height) => base * height / 2;
```
<br>
引数が一個の場合には、引数をくくるカッコも省略可能

```script.js
let getCircle = radius => radius * radius * Math.PI;
```

※Math.PIプロパティは円周率、約3.14159を表す
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/PI


# 最後に

JavaScriptの関数の基本的な構文を理解するのは以上の4つになります。
それぞれの関数の定義の方法だけでなく、その違いや特徴、どのユーザー定義関数で関数を定義するべきなのか理解を深めていく必要があると実感しています。


今回は基本的な内容について解説してきましたが、今後も学習した内容をより詳しくまとめていこうと思います。