MENU

【JavaScript】関数(function)の使い方を解説|Webの基礎

JavaScriptでの関数の使い方の解説|Webの基礎
目次

はじめに

前回の記事では、正規表現(RegExp)の使い方を解説しました。

今回は、一連の処理をひとまとまりにして名前を付け、何度でも呼び出せるようにする関数(Function)の基本的な使い方を解説します。これまでの記事でもaddEventListenerforEachmapfilterなどに(event) => { ... }のような書き方を何度も登場させてきましたが、今回はその「関数」そのものの意味と書き方を整理します。

関数とは?

関数とは、複数の処理をひとまとめにして名前を付け、必要なときに何度でも呼び出せるようにする仕組みです。同じ処理を毎回書き直す必要がなくなり、コードの見通しもよくなります。

VBAのSubプロシージャやFunctionプロシージャと同じ発想です。VBAでは戻り値の有無でSubFunctionを使い分けますが、JavaScriptでは区別がなく、どちらも同じ書き方で定義し、必要であればreturnで戻り値を返します。

関数の定義方法(関数宣言・関数式・アロー関数)

JavaScriptには関数の定義方法が3種類あります。

// ① 関数宣言
function greet(name) {
    return `こんにちは、${name}さん`;
}

// ② 関数式(変数に関数を代入する)
const greet2 = function (name) {
    return `こんにちは、${name}さん`;
};

// ③ アロー関数(関数式をより短く書ける記法)
const greet3 = (name) => {
    return `こんにちは、${name}さん`;
};

console.log(greet("佐藤"));  // "こんにちは、佐藤さん"
console.log(greet2("鈴木")); // "こんにちは、鈴木さん"
console.log(greet3("田中")); // "こんにちは、田中さん"

3つとも動作は同じですが、①の関数宣言だけは定義した位置より前のコードから呼び出せるという違いがあります(巻き上げと呼ばれる仕様のためです)。②の関数式と③のアロー関数は、定義した行より後でないと呼び出せません。

関数式・アロー関数を定義前に呼び出すと、「Cannot access ‘greet2’ before initialization」のようなエラーになります。関数を使う場合は、定義してから呼び出す順序を意識しましょう。

現在の実務では③のアロー関数が最もよく使われます。特に、addEventListenerforEachのように関数を引数として渡す場面では、アロー関数のほうが短く書けて便利です。

引数の書き方(デフォルト値・複数引数)

関数に渡す値(引数)は、,(カンマ)区切りで複数指定できます。また、引数を省略した場合の初期値(デフォルト値)も設定できます。

function calcTotal(price, taxRate = 0.1) {
    return Math.floor(price * (1 + taxRate));
}

console.log(calcTotal(1000));       // 1100(taxRateを省略するとデフォルト値0.1が使われる)
console.log(calcTotal(1000, 0.08)); // 1080(taxRateを指定するとその値が優先される)

taxRate = 0.1のように引数名の後ろに= 値を書くと、呼び出し時にその引数が省略された場合だけデフォルト値が使われます。VBAのOptional引数に近い機能です。

戻り値(return)とアロー関数の省略記法

関数の処理結果を呼び出し元に返すにはreturnを使います。returnが実行されると、それ以降の処理は実行されずに関数を抜けます。

function double(n) {
    return n * 2;
    console.log("この行は実行されません"); // returnの後なので到達しない
}

console.log(double(5)); // 10

アロー関数では、処理が1行の式だけの場合に限り、{}returnを省略して書くことができます。

const double2 = (n) => n * 2; // {}とreturnを省略した書き方
console.log(double2(5)); // 10(上のdoubleと全く同じ結果)

{}を省略した場合は「式の結果がそのまま戻り値になる」という決まりのため、{}を書いて複数行の処理にする場合はreturnを省略できません。

変数のスコープ(関数の中と外)

関数の中でconstletで宣言した変数は、その関数の中だけで使えるローカル変数になり、関数の外からは参照できません。

function showMessage() {
    const message = "こんにちは"; // 関数内だけで使えるローカル変数
    console.log(message); // "こんにちは"
}

showMessage();
console.log(message); // ReferenceError: message is not defined

このように、変数が「どの範囲で使えるか」をスコープと呼びます。関数の外で宣言した変数(グローバル変数)は関数の中からも参照できますが、関数の中の処理結果を外に渡したい場合は、グローバル変数に頼らずreturnで戻り値として渡すほうが、どこで何が変更されたか分かりやすく安全です。

値として渡される関数(コールバック関数の振り返り)

JavaScriptでは、関数を値として変数に代入したり、他の関数の引数として渡したりできます。このように引数として渡される関数をコールバック関数と呼びます。実は、これまでの記事でもコールバック関数を数多く使ってきました。

// JS-06で解説したイベント処理
button.addEventListener("click", (event) => {
    console.log("クリックされました");
});

// JS-13で解説した配列の操作
const doubled = [1, 2, 3].map((n) => n * 2);

addEventListenerの第2引数やmapの引数に渡している(event) => { ... }(n) => n * 2は、どちらも「その場で定義した名前のない関数(無名関数)」です。これらは今回解説した関数の書き方そのものであり、イベント処理を解説した記事配列の操作を解説した記事で暗黙的に使ってきたのは、この仕組みだったというわけです。

実務サンプル(送料を含めた合計金額の計算)

これまでに解説した関数の書き方(デフォルト引数・戻り値)と、配列の操作を解説した記事reduceを組み合わせて、カートの商品から送料込みの合計金額を計算する関数を作ります。

HTML

<div id="cartResult"></div>

JavaScript(main.js)

document.addEventListener("DOMContentLoaded", () => {
    const cartItems = [
        { name: "ノートPC", price: 45000, quantity: 1 },
        { name: "マウス", price: 1500, quantity: 2 },
    ];

    // 送料・送料無料の基準額をデフォルト引数で指定
    function calcCartTotal(items, shippingFee = 500, freeThreshold = 5000) {
        const subtotal = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
        const shipping = subtotal >= freeThreshold ? 0 : shippingFee;

        return {
            subtotal,
            shipping,
            total: subtotal + shipping,
        };
    }

    const result = calcCartTotal(cartItems);

    document.getElementById("cartResult").innerHTML = `
        <p>商品小計:${result.subtotal.toLocaleString()}円</p>
        <p>送料:${result.shipping === 0 ? "無料" : result.shipping.toLocaleString() + "円"}</p>
        <p>合計:${result.total.toLocaleString()}円</p>
    `;
});

calcCartTotal関数は、送料と送料無料の基準額を引数で受け取れるようにしつつ、デフォルト値を設定しているため、呼び出し側でcalcCartTotal(cartItems)とだけ書けば標準の条件で計算されます。計算結果はオブジェクトとしてreturnし、呼び出し元でそれぞれの値を使って画面に表示しています。

カート小計・送料・合計の表示イメージ

よくある質問・エラー対処

Q. 関数宣言と関数式・アロー関数は、結局どちらを使えばいいですか?

→ 迷ったらアロー関数で問題ありません。ただし、定義した位置より前で呼び出したい場合(読み込み順序に依存したくない場合)は、巻き上げが効く関数宣言を使うと安全です。


Q. アロー関数と通常の関数(function)で動作が違う点はありますか?

→ 最も大きな違いはthisの扱いです。通常の関数は呼び出し方によってthisの指す対象が変わりますが、アロー関数はthisを自分では持たず、外側のスコープのthisをそのまま使います。オブジェクトのメソッドとして関数を定義する場合など、thisを意図通りに使いたい場面ではこの違いに注意してください。


Q. 関数に渡す引数の数を間違えてもエラーにならないのはなぜですか?

→ JavaScriptの関数は、引数の数が定義と呼び出しで一致していなくてもエラーになりません。足りない引数はundefinedとして扱われます(デフォルト値を設定していれば、その値が使われます)。逆に多く渡した分の引数は無視されます。厳密にチェックしたい場合は、関数の中でundefinedかどうかを確認する処理を書く必要があります。

おわりに(まとめ)

まとめ

関数を使うと、処理をひとまとめにして再利用できるようになり、コードの見通しがよくなります。

  • ✅ 関数の定義方法には関数宣言・関数式・アロー関数の3種類があり、実務ではアロー関数がよく使われる
  • ✅ 関数宣言だけは定義前でも呼び出せる(巻き上げ)
  • ✅ 引数には`引数名 = 値`でデフォルト値を設定できる
  • ✅ 処理結果を呼び出し元に返すには`return`を使う。アロー関数は1行の式なら`{}`とreturnを省略できる
  • ✅ 関数内で宣言した変数は、その関数の中だけで使えるローカル変数になる
  • ✅ addEventListenerやmapなどに渡してきた`(event) => {…}`も、今回解説した関数そのものだった

これまでの記事で書いてきたコードを、関数という視点で見直してみましょう。

次回は、条件分岐・繰り返し(if文・for文など)について解説予定です。

この記事が、少しでも誰かのお役に立てれば幸いです。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


【CSS】テキスト関連プロパティについて基本解説|Webの基礎


よかったらシェアしてね!
  • URLをコピーしました!
目次