関数リテラル?無名関数?アロー関数?
一体こいつらは何なのでしょうか。
彼らを一言で説明すると「関数の短縮形」です。
「そもそも関数って何や?」という方は、まず関数を知りましょう!
それでは、関数リテラルや無名関数、アロー関数それぞれについて、違いや特徴を見ていきましょう。
サンプルコードの使い方
コード右上のアイコンをクリックすることでコピーできます。
見出しが「サンプルコード」のコードは、空っぽのhtmlファイルにコピペするだけで結果を確認することができます!

それでは本文へ、レッツゴー!
関数リテラルと無名関数と匿名関数の違いは?
まず「関数リテラル」と「無名関数」と「匿名関数」は全く同じで、呼び方が違うだけです。
「全く同じものに何で名前が3つもあるんだよ。ややこしいなくそ!」
と思ったそこのあなた。その通りです。
「みそ汁」と「味噌汁」と「miso soup」くらいの違いです。
ちなみにリテラルとは「文字通り」という意味です。
この記事では呼び方を「無名関数」で統一することにしましょう。
さて、文字通り無名関数とは、名前のない関数のことです。
関数を宣言する際、関数名を設定するのがお約束でしたね。
その関数名使わない関数のことを、無名関数と言います。
無名関数の書き方は、関数名を丸ごと撤去するだけでOKです。
function(){
実行したい処理;
}
これだけなのですが、実際では無名関数を変数に格納することが多いです。
const 変数名 = function(){
実行したい処理;
}
変数に格納した無名関数を実行してみる!
通常の関数を実行する場合の記述は、
関数名(引数);
でしたが、
変数に格納した無名関数の場合の宣言は、
変数名(引数);
となります。
ほぼ同じですね。
サンプルコード
<script>
const hello = function(arg){
console.log(arg);
};
hello('おっす!');
</script>
「いや通常の関数と何が違うの?関数名か変数名だけかの違いじゃん。メリットが感じられないよ。」って感じですよね。
最初のうちは特に変数に格納しなくても何ら問題はないのですが、今後記述に慣れてくると、関数の中身もどんどん複雑になっていきます。
そんな時に、関数を変数に格納しておくと、とっても見やすく使いやすいのです。
この良さは、慣れてこないと実感しにくいところです。
後ほど、無名関数を変数に格納したものとしていないものの比較ができるサンプルコードを用意しています。
引数に関数を求めている子たちがいる
引数に関数そのものを求めている子が多く存在します。
例えば、setIntervalを見てみましょう。
setInterval(関数, ミリ秒);
setIntervalとは、JavaScriptに標準で搭載されている機能で、「ミリ秒」ごとに「関数」を発火してくれます。
第二引数には、何ミリ秒ごとに発火させたいかの数字を、第一引数には発火させたい関数を入れることがルールとして決まっています。
この子は関数の実行をせずとも実行してくれるので、もはや関数名を必要としません。
そのため、関数名を省略します。
それでは実際に使ってみましょう!
サンプルコード
以下のコードは、1秒ごと(1000ミリ秒ごと)に、経過時間をコンソールに出力してくれます。
せっかくなので、変数に格納しない場合とする場合の2パターン用意しておきます。
どちらも同じ動きをします。
<script>
/*--------------------------------
無名関数を変数に格納しないパターン
---------------------------------*/
/* 数字をカウントして入れておく変数を用意 */
let count = 0;
/* setInterval(関数, ミリ秒) */
setInterval(function(){
count++;
console.log(count);
},1000);
/*--------------------------------
無名関数を変数に格納するパターン
---------------------------------*/
/* 数字をカウントして入れておく変数を用意 */
let count2 = 0;
/* 無名関数を変数に格納する */
const timeCount = function(){
count2++;
console.log(count2);
};
/* setInterval(関数, ミリ秒) */
setInterval(timeCount, 1000);
</script>
letが分からない方はこちら
console.log()が分からない方はこちら
関数そのものを引数として用いる場合、その関数に引数を設定することができないので注意してください。
どうしてもその関数に引数を使いたい場合、さらに関数で囲んで、それを実行することで使うことができます。
以下のコードは、引数に入れたワードを1秒ごと(1000ミリ秒ごと)にコンソールに出力します。
<script>
// 引数を入れた通常の関数「timeCountFunction」を用意する
function timeCountFunction(arg){
// setInterval(関数, ミリ秒)
setInterval(function(){
console.log(arg);
},1000);
}
// 関数「timeCountFunction」を実行する
timeCountFunction('うぇい');
</script>
さらに記述を短縮!アロー関数
無名関数で関数名を省略できるようになりましたが、これをさらに省略することができます。
別に省略しなくてもいいので、ここまででちょっとしんどくなってきた方は、流し見で「ふーん」くらいでもOKです。
アロー関数とは、無名関数の記述を短縮させたものです。
アロー関数の宣言は以下のようになります。
(引数)=>{
実行したい処理;
};
引数の左側にあった「function」が消え、代わりに右側に「=>」(矢印)がくっつきます。
地味な違いでしかないのですが、慣れてくると記述がずいぶん楽になります。
サンプルコード
無名関数とアロー関数で比較してみましょう。
本当に些細な違いです。
<script>
/* 無名関数の場合 */
let count = 0;
setInterval(function(){
count++;
console.log(count);
},1000)
/* アロー関数の場合 */
let count3 = 0;
setInterval(()=>{
count3++;
console.log(count3);
},1000);
</script>
アロー関数は他の関数宣言とはthisの対象が異なる
アロー関数と他の関数とでは、thisの対象が異なります。
疲れてきた方は読み飛ばしてOKです。
通常の関数:記述した位置によってthisの対象が変化する
アロー関数:アロー関数が定義された位置によりthisが固定化される
thisで困ったらアロー関数から通常の関数に書き換えればそれでOKなので、大した問題ではありません。
ただ、「違うんだ」ということだけわかっておきましょう。
サンプルコード
<button class="functest">this参照</button>
<script>
let literal = function(){
console.log(this);
}
let arrow = () =>{
console.log(this);
}
const functest = document.querySelector('.functest');
functest.addEventListener('click', literal);
functest.addEventListener('click', arrow);
</script>
無名関数、アロー関数のまとめ
- 通常の関数から関数名を省略すると、無名関数(匿名関数、関数リテラル)
- 無名関数をさらに短縮させたものが、アロー関数
/* 無名関数 */
function(){
実行したい処理;
}
/* アロー関数 */
()=>{
実行したい処理;
}
コールバック関数とかいうやつもあります
関数にはまだ「コールバック関数」と呼ばれるものがあります。
「もう十分だろ、登場しないでくれ。」
ということで、また別記事での紹介となります。
コールバック関数は割と複雑な関数での登場となるので、まだ気にしなくてもいいかもしれません。
お疲れ様でした。