JavaScriptの関数がオブジェクト型として振る舞うものとして、変数として関数を格納したり、関数を別の関数への引数として渡したり、返り値として関数を返すこともできるわけですが、関数を引数にとる高階関数の形をすでに見てきました。
ここでは、関数を返す関数を見て行こうと思います。
関数を返す関数
関数を戻り値として返す関数を次のように書いてみました。
function jobQuestion(job) {
if (job === '錬金術師') {
return function(name) {
console.log(name + '、 錬金術の「一は全、全は一」について教えてください。');
};
}
関数はjobQuestion()として、引数にjobを持ちます。戻り値には引数にnameを持つ無名関数をreturnで返すことにしていますが、その条件としてif文で条件式を与えています。無名関数の処理はconnsole.log()で文章を表示するものにしています。(ちなみに漫画の「鋼の錬金術師」をネタにしています)
このコードのif文の条件を増やして、コードを次のように変更してみます。
function jobQuestion(job) {
if (job === '錬金術師') {
return function(name) {
console.log(name + '、 錬金術の「一は全、全は一」について教えてください。');
};
} else if (job === '機械鎧整備士') {
return function(name) {
console.log('ラッシュバレーの機械鎧はどうですか、' + name + '?');
};
} else {
return function(name) {
console.log('こんにちは、' + name + '。ご機嫌いかが?');
};
}
}
条件が3つに別れました。jobの値の違いで、返す無名関数が異なっているのがわかると思います。
この関数は次のように呼び出すことができます。
var alchemistQuestion = jobQuestion('錬金術師');
var automailQuestion = jobQuestion('機械鎧整備士');
それぞれ変数を用意していますが、これは引数がそれぞれの条件にあった関数が返されていることになります。ただし、このままではブラウザのJavaScriptコンソールには何も表示されません。
続けて、次のように呼び出してみます。
alchemistQuestion('エドワード');
automailQuestion('ウインリィ');
先ほどの変数には関数が返されているので、それに引数を与えています。
これを実行すると、JavaScriptコンソールには次のように表示されます。
条件にあった表示がなされているのがわかります。
これに続けて、3つnameを指定して追加してみます。
alchemistQuestion('エドワード');
automailQuestion('ウインリィ');
alchemistQuestion('アルフォンス');
alchemistQuestion('イズミ');
alchemistQuestion('ロイ');
JavaScriptコンソールには次のように表示されます。
同様に表示できるのがわかります。
ここまでは、最初の関数で一旦条件式に引数を渡して判定したものを変数に格納して、それに対して再び引数を与えて呼び出していました。
今度は次のようにしてみます。
jobQuestion('錬金術師')('エルリック兄弟');
最初の関数に条件式で判定する値を入れて呼び出し、さらに続けて引数を渡す形にしています。
これは左から順に実行していくので、これでもこれまでと同様に呼び出すことができます。JavaScriptコンソールには次のように表示されます。
とても見慣れない形ですが、こうすることで一度に呼び出すことができるので便利です。
まとめ
ここでは、関数を戻り値として返す関数を定義して操作してみました。
戻り値の関数を呼び出した後に、関数を実行する方法もありますが、関数から一度に戻り値の関数を呼び出す方法も見てみました。括弧が2つ続くので見慣れないやり方ではありますが、操作自体は簡単ですから便利に扱えると思います。