JavaScript学習 - 関数 -

#JavaScriptにおける『関数』
関数そのものの仕組み(入力に対してなんらかの処理を行い、その結果を返す)はJavaと同じ。
JavaScriptでは関数は`データ型の一種`として扱うのがJavaとの大きな違い。

・『関数の引数に名前を指定する』
・『複数の戻り値をそれぞれ指定した変数に代入する』 ...etc

型推論もあるので、かなり柔軟に関数や変数の設定が出来る。


#関数の定義

主に以下の4つ(3つの)の方法がある

・ `function命令による定義`
・ functionコンストラクターによる定義
・ `関数リテラルによる定義(無名関数)`
・ `アロー関数による定義`

これら4つのうちfunctionコンストラクターは外部から任意のコードが実行できてしまう可能性があるので使用は推奨されていない、原則としてfunction命令・関数リテラルあるいはアロー関数のどれかで定義することになるので実際には3つの方法ということになる。

## function命令による定義
関数の定義の最も基本的な方法。

```javascript:function命令
function hoge(hage, ...){
   //任意の処理
   return piyo
}
```

関数の実装といえば基本的にはこれ。
関数の中に関数を実装したり、処理の中で一回限りの処理をする関数を実装したい場合は後述の`関数リテラル`や`アロー関数`などを使う。

## 関数リテラル・アロー関数
`匿名関数`、`無名関数`とも呼ばれる。
変数として代入したり、関数の引数や戻り値として利用できるので非常に柔軟なコーディングができるようになる。

```javascript:関数リテラル
 var hoge = function(hage, piyo){
   return hoge * piyo
}
```

アロー関数を利用する事でfunctionキーワードを省略できるのでさらにシンプルに記述できるようになる。

```javascript:アロー関数
 var hoge = (hage, piyo) => return hoge * piyo;
```

引数が1つの場合は引数の()も省略することが出来る。
省略する際は引数が**0個の場合**は省略できないので注意。

#変数のスコープ

変数がコードのどの部分から参照できるのかを表す概念的なもの。
以下の3種類のスコープがある。
・ `ローカルスコープ`
・ `グローバルスコープ`
・ `ブロックスコープ`

ローカルスコープとptにおける『関数』
関数そのものの仕組み(入力に対してなんらかの処理を行い、その結果を返す)はJavaと同じ。
JavaScriptでは関数は`データ型の一種`として扱うのがJavaとの大きな違い。

・『関数の引数に名前を指定する』
・『複数の戻り値をそれぞれ指定した変数に代入する』 ...etc

型推論もあるので、かなり柔軟に関数や変数の設定が出来る。


#関数の定義

主に以下の4つ(3つの)の方法がある

・ `function命令による定義`
・ functionコンストラクターによる定義
・ `関数リテラルによる定義(無名関数)`
・ `アロー関数による定義`

これら4つのうちfunctionコンストラクターは外部から任意のコードが実行できてしまう可能性があるので使用は推奨されていない、原則としてfunction命令・関数リテラルあるいはアロー関数のどれかで定義することになるので実際には3つの方法ということになる。

## function命令による定義
関数の定義の最も基本的な方法。

```javascript:function命令
function hoge(hage, ...){
   //任意の処理
   return piyo
}
```

関数の実装といえば基本的にはこれ。
関数の中に関数を実装したり、処理の中で一回限りの処理をする関数を実装したい場合は後述の`関数リテラル`や`アロー関数`などを使う。

## 関数リテラル・アロー関数
`匿名関数`、`無名関数`とも呼ばれる。
変数として代入したり、関数の引数や戻り値として利用できるので非常に柔軟なコーディングができるようになる。

```javascript:関数リテラル
 var hoge = function(hage, piyo){
   return hoge * piyo
}
```

アロー関数を利用する事でfunctionキーワードを省略できるのでさらにシンプルに記述できるようになる。

```javascript:アロー関数
 var hoge = (hage, piyo) => return hoge * piyo;
```

引数が1つの場合は引数の()も省略することが出来る。
省略する際は引数が**0個の場合**は省略できないので注意。

#変数のスコープ

変数がコードのどの部分から参照できるのかを表す概念的なもの。
以下の3種類のスコープがある。

・ `ローカルスコープ`　:関数の外で宣言した変数
・ `グローバルスコープ` :関数の中で宣言した変数
・ `ブロックスコープ` :if文などの{}内で宣言した変数

ローカル・グローバルなどと名がついているので身構えてしまうが基本はJavaと同じである。
ES2015にてブロックスコープが実装されたため、挙動は基本的にJavaと似たような感じになった。

#引数

主に以下の3つの機能があげられる。

・引数のデフォルト値
・可変長引数
・名前付き引数

ES2015までは実装にオブジェクトを必要としたが、ES2015からは実装にあたっての記法が簡略化され、簡素なコードでより柔軟なコーディングが可能になった。

##引数のデフォルト値

『仮引数 = デフォルト値』の形式で記述することで仮引数にデフォルトの値を設定できる

```javascript:デフォルト値の設定
 function gethoge(hage = 1, piyo = 1){
   return hage * piyo / 2
}  
```

if文などで条件文気してやる必要がなく、簡単に実装できる。
例外をスローするだけの関数をデフォルト値として利用することで必須の引数を宣言することもできる。
`hage = 1, piyo = hoge * 2`　のように引数のデフォルトに仮引数の値を利用する事もできる。
仮引数の値を利用する際は自身より後に定義された引数は使えないので注意(上記のケースの場合、hageのデフォルト値にpuyoの値を使おうとするとエラーが起こる)。
また、関数呼び出しの引数に`null`を使うとデフォルト値ではなくnullが代入してしまう点、デフォルト値を設定した引数は引数の末尾に追加しないと思わぬ値が入ってしまうことがある事にも注意。

##可変長引数の関数

仮引数の前に`...` を入れることで可変長引数となる。
これによって、任意の数の引数を配列としてまとめて受け取る事が出来るようになる

```javascript:可変長引数の定義
 function hoge(...piyos){
   //任意のコード
   return piyos
}  
```

配列として受け取るのでlengthやpush/shiftなどのすべての配列操作が可能。
また実引数で `...`　演算子を利用することで、配列内のすべての数値を展開可能。Math.maxメソッドなど配列の受け取りを許容していないメソッドに有効。

##名前付きの引数

`{プロパティ名 = デフォルト値}`の形で記述する事で、名前付きの引数を簡素に表現する事が出来る。

```javascript:引数に名前を付けて定義
 function hoge({hage = 1, piyo = 1}){
   //任意のコード
   return piyos
}  
```

一度オブジェクトリテラル`{}`として渡された引数を分解して個別の値としてアクセスしている、やっていることはフィールドの値を取り出すのに近い
オブジェクトなので複数値を持つこともできる、値を取り出すときはプロパティ名を指定してやると値を取り出せる。呼び出し側のコードを変えることなく取り出す値を変えたりする時に便利。



長くなってしまったので今回はここまで