034.3 JavaScript の制御構造と関数(独自関数編)
Web Development Essentials | 2024/07/17

本章は前回の記事の続きであり、内容(※JavaScript の制御構造と関数(制御構造編))を理解していることを前提に進めます。多くのプログラミング言語には、言語の仕様にあらかじめ用意されている関数以外にも、開発者が独自に定義した関数を記述してプログラムを作り上げることができます。本章では、関数の定義や呼び出し方について詳しく説明していきます。

関数の定義

関数とは、一連の手続きを1つの処理としてまとめ、それに名前を付けたコードブロックです。プログラムの規模が大きくなるにつれて、関数を使用しないでコードを管理することは難しくなります。例えば、整数を二乗する処理がプログラムの複数の箇所で必要とされる場合、その計算を行うコードをそれぞれの場所に書かなければなりません。さらに修正等でコードを変更する場合、該当する全ての個所で変更を加えなければならないため、管理が大変となります。

しかし、関数を定義した場合、整数を二乗する処理を記載した関数を呼び出すだけで済み、修正等でコードを変更する際は、関数内の処理を変更するだけで済むようになります。

JavaScriptの関数の形式は「function」キーワードから始まり、その後ろに関数名を記述します。関数名の後には「()(括弧)」を付け、必要に応じて括弧内に「引数(仮引数)」を記述します。そしてブロック内に関数の内容を記述し、「return」キーワードから、関数の実行結果を戻り値として返します。

前述の通り、関数は必要に応じて引数(仮引数)を記述し、定義した関数を呼び出す際は引数(実引数)に受け渡す値を指定します。

以下は、2つの数値を引数として受け取り、その加算結果を戻り値として返す関数numbersの記述例と表示結果です。

■記述例(JavaScript)

//加算する関数
function numbers(num1, num2) {
    return num1 + num2; //num1とnum2の加算結果を返す値
}

//関数を呼び出し、結果を表示
console.log(numbers(3, 5));

関数numbersの定義では、仮引数には「num1」と「num2」という数値を取得する変数を指定します。関数numbersを呼び出すとき、引数num1には3を、num2には5を受け渡しているため、計算結果として8が表示されます。

また関数の定義に引数は必須では無いため、引数を利用しない場合は()の中は省略して記述します。
以下は、文字列「Hello, World!」を返す関数messageの記述例と表示結果です。

■記述例(JavaScript)

// あいさつメッセージを返す関数
function message() {
    return "Hello, World!";
}

// 関数を呼び出し、結果を表示
console.log(message());

また、ソースコードが読み込まれた際に関数の定義は最初に解析されるため、関数は記述位置に限らず、どこからでも呼び出すことが可能です。

以下は、関数nameを定義する前に呼び出す記述例と表示結果です。

■記述例(JavaScript)

// 関数nameを呼び出す
console.log(name());

// 関数nameの定義
function name() {
    return "Yamada Taro";
}

関数は複数のreturnキーワードを利用して、条件に応じて戻り値を返すことが可能ですが、returnキーワードは必須では無いため、値を返さない関数も定義できます。returnキーワードで値が返却される事のない結果を受け取ろうとした場合、戻り値は「undefined」になります。

以下は、色名に基づいた文字列を返す関数colorの記述例と表示結果です。

■記述例(JavaScript)

function color(color) {
    if (color == "red") {
        return "赤色です";
    } else if (color == "blue") {
        return "青色です";
    }
}

console.log(color("red"));
console.log(color("blue"));
console.log(color("green"));

上記では、関数colorの引数に文字列「red」または「blue」を渡すと、if文によって「赤色です」と「青色です」がそれぞれ表示されますが、「green」を渡した場合は一致する条件がなく、戻り値が無いため「undefined」と表示されることがわかります。

関数式

JavaScriptでは、関数は単なるオブジェクト型の一種として扱われるため、変数のように扱うことも可能で、変数に代入された関数のことを「関数式」といいます。関数式の場合、定義した変数の名前が関数名となるため、関数自体に名前を付ける必要はありません。こういった関数のことを「無名関数」といいます。

以下は、加算を行う関数を関数式numbersとして定義した記述例と表示結果です。

■記述例(JavaScript)

let numbers =  function (num1, num2) {
    return num1 + num2;
}

console.log(numbers(3, 5));

なお、関数式は変数と同じ扱いとなるため、関数式を定義した後に呼び出す必要があり、定義前に呼び出すと参照エラーが発生します。

以下は関数式numbersを定義前に呼び出した記述例と表示結果です。

■記述例(JavaScript)

console.log(numbers(3, 5)); //関数式numbersを定義前に呼び出す

//関数式numbersを定義
let numbers =  function (num1, num2) {
    return num1 + num2;
};

関数式は、ある関数を別の関数の引数として渡すときに便利です。例えば、特定の数値を含む配列があり、それぞれの要素を二乗した配列を返す関数を定義する場合、以下のように記述することができます。

■記述例(JavaScript)

//二乗する関数式
let nijo = function(num) {
    return num * num;
};

 //配列のそれぞれの要素にfunc関数を適用し、新しい配列を返す
function map(arr, func) {
    let result = [];
    for(let n of arr) {
        result.push(func(n)); // 関数funcを適用した結果を配列resultに追加
    }
    return result;
}

let arr = [1,2,3,4];
console.log(map(arr,nijo));

上記では、map関数に配列とnijoの変数式を渡し、その結果をcosole.logにて出力しています。
詳しく流れをみていくと、map関数の定義では、変数arrと変数funcを引数として指定し、変数arrには配列を、変数funcには関数式をそれぞれ引数として取得しています。
map関数では、配列を取得した変数arrをfor文を使って繰り返し処理を実行し、変数式として代入された変数funcへ引数として渡しています。
変数funcに格納されている関数式nijoでは、引数に配列の各要素の数字を引き取り、二乗にした結果を返している為、結果的に配列arrを二乗した配列[1, 4, 9, 16]が生成されます。

再帰関数

再帰関数とは、定義している関数内で自分自身の関数を呼び出す関数のことを指します。再起関数は同じ処理を繰り返し実行し、特定の終了条件が満たされた時点で呼び出しが停止します。もし終了条件を設けない場合、関数は無限に自身を呼び出し続けてしまい、プログラムに深刻な問題を引き起こす可能性があるため、再帰関数の作成には注意が必要です。

以下は、1から10の和を再帰関数を用いて算出した記述例と表示結果です。

■記述例(JavaScript)

function funcSum(num, sum = 0) {
    // 関数の処理を行う: 現在の数を和に加える
    sum += num;
    // 再帰の終了条件: numが10に達した場合
    if (num >= 10) {
        return sum;
    }
    // 関数を再帰的に呼び出し、次の数を加算
    return funcSum(num + 1, sum);
}

// 再帰関数の引数numに1を代入し、呼び出す
let result = funcSum(1);
console.log(result); // 最終的な和を表示する: 55

上記では、変数resultにfuncSum関数を定義し、関数の結果をconsole.logに出力している記述例となりますが、上記の記述例で何か違和感はありませんか。。?

ここまで本章を真剣に読み、学習に取り組んでいる方はもう既にお気づきかと思いますが、funcSum関数の呼び出し時と定義時で引数の数が異なっています。
これはfuncSum関数の定義時、第2引数にデフォルト値を設定している為、呼び出しの場面によって引数の値を省略することができる為です。このように引数にデフォルトの値を設定することをデフォルト引数といいます。

では、上記記述例の説明を行っていくと、関数funcSumの第2引数sumにはデフォルト値として0が設定されており、funcSum関数を初めて呼び出す時では、第2引数の値を0から変更する必要が無いため、第2引数の値は省略しています。
この第2引数sumに変数numの値を加算し、numの値が10に達するまでfuncSumを再帰的に呼び出し、累積和が計算されます。再帰関数の終了条件はnumの値が10以上となり、条件を満たすと関数は合計値sumを返して処理を終了します。

 関数はプログラムを書く上で非常に便利ですが、正しく記述や使用をしないと、期待した通りには動作しません。関数の種類によっては関数の呼び出し位置にも注意が必要です。本試験では関数の形式などの穴埋め問題や、関数を呼び出した際の実行結果について問われやすいかなと思います。それぞれのコードの読み書きが行えるまで内容を理解し、学習を行いましょう!

それでは、今回はここまで〜。

PAGE TOP