メインコンテンツまでスキップ

無名関数

無名関数

イベントの節で、関数も値の一種であることを説明しました。このため、関数は変数やプロパティに代入したり、関数の引数や戻り値になったりできます。

しかしながら、通常の記法で関数を記述することが煩わしい場合があります。イベントハンドラを登録する場合を考えてみましょう。

index.html
<button id="greet-button">Click me</button>
script.js
function onGreetButtonClick() {
alert("こんにちは!"); // ダイアログボックスを表示
}

document.getElementById("greet-button").onclick = onGreetButtonClick;

この場合、関数onGreetButtonClickは、イベントハンドラとして登録されるためだけに利用されており、onGreetButtonClickという名前自体はあまり重要ではありません。こういった場合、関数オブジェクトの生成をするための式(関数式)を用いることができます。このようにして生成された関数は、名前を持たないため、無名関数と呼ばれます。

先ほどのプログラムを関数式を用いて書き換えると、次のようになります。

script.js
document.getElementById("greet-button").onclick = () => {
alert("こんにちは!");
};

JavaScriptにおける関数式の構文は、次のとおりです。=>の記号が特徴的な構文となっています。

(引数1, 引数2) => {
処理;
}
無名関数を用いて関数定義を書き換える

通常の関数定義の構文は、ほとんど関数式を使用して書き換えることができます。次のプログラムにおいて、add1add2はほとんど等価なものとみなすことができます。

function add1(a, b) {
return a + b;
}

const add2 = (a, b) => {
return a + b;
};
アロー関数

この項で扱った無名関数式を、=>記号が矢のように見えることから、アロー関数と呼ぶことがあります。JavaScriptには、アロー関数の他にもう一つ、無名関数を記述する方法があります。

const add3 = function (a, b) {
return a + b;
};

古い文献ではこちらの記法が採用されている場合がありますが、現代ではほとんど用いられません。

無名関数を用いると便利な関数

Array#mapメソッドは、引数として関数をひとつとり、配列の各要素に適用した上で、その戻り値からなる新しい配列を返します。

このように、他の関数の引数として呼び出される関数のことをコールバック関数と呼びます。

const pricesWithoutTax = [100, 200, 300, 400, 500];
const taxRate = 0.2;
const pricesWithTax = pricesWithoutTax.map((price) => {
return price * (1 + taxRate);
});
document.write(pricesWithTax); // 120,240,360,480,600

アロー関数の省略形

アロー関数は、内部の処理がreturn文のみの場合、波括弧とreturnキーワードを省略して式のみを記述することもできます。前項のサンプルプログラムは、次のように省略可能です。

const pricesWithTax = pricesWithoutTax.map((price) => price * (1 + taxRate));

演習

問題1

先ほどのArray#mapメソッドを用いてみましょう。students変数に格納されている名前を箇条書きにしてください。

const students = ["Hazel", "Dorian", "Scarlett", "Daisy"];
// ここでHTML要素を取得し、学生の名前を箇条書きとして表示
ヒント
  • innerHTMLプロパティにより、HTML要素を取得・変更できます。
  • 箇条書きにはulタグやliタグを使用します。
  • joinメソッドを配列要素を指定された文字列で連結するのに使います。
解答例: 箇条書き
const students = ["Hazel", "Dorian", "Scarlett", "Daisy"];
const studentList = document.getElementById("student-list");
studentList.innerHTML = students
.map((student) => `<li>${student}</li>`)
.join("");

問題2

scores変数には、各必修科目の点数が格納されているとします。全ての要素が50点以上であることを確認するには、何というメソッドを使うのが適切か調べてみてください。また、実際にそのメソッドを用いて点数を確認してみてください。

const scores = [90, 65, 70, 55, 80];
if (/* すべての点数が50点以上なら */) {
document.write("進級できます");
}
ヒント

「全ての要素が特定の条件を満たすかどうか」を調べるメソッドがあります。

解答例: 進級可能?

Array#everyメソッドを使うと、配列の全要素が指定された関数でテストできます

const scores = [90, 65, 70, 55, 80];
if (scores.every((score) => score >= 50)) {
document.write("進級できます");
}

問題3 (発展)

Array#reduceメソッドは、Arrayクラスのメソッドの中でも特に使い方の難しいメソッドです。ドキュメントをよく読み、このメソッドを用いて配列の最小値を求めてみましょう。

const scores = [90, 65, 70, 55, 80];
const minScore = scores.reduce(/* コールバック関数 */);
document.write(minScore); // 55
解答例: Array#reduce メソッドの使い方
const scores = [90, 65, 70, 55, 80];
const minScore = scores.reduce((previousValue, currentValue) => {
if (previousValue > currentValue) {
return currentValue;
}
return previousValue;
});
document.write(minScore); // 55