初心者必見!JavaScript無名関数の使い方10選

JavaScriptの無名関数について解説するイメージJS
この記事は約9分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事を読めば、JavaScriptの無名関数の使い方ができるようになります。無名関数は、JavaScriptを使ってプログラムを書く上で非常に便利な機能です。

しかし、初心者には分かりづらい部分もあります。

この記事では、無名関数の基本から応用例、注意点までをわかりやすく解説していきます。

JavaScript初心者の方でも安心して読める内容になっています。

●JavaScript無名関数とは

○無名関数の基本

無名関数とは、名前を持たない関数のことです。

JavaScriptでは、関数を変数に代入したり、引数として渡すことができます。

無名関数は、そのような場合に便利な機能となっています。

●無名関数の使い方

○サンプルコード1:イベントリスナーに無名関数を使う

下記のサンプルコードでは、HTMLのボタン要素に対して、クリックイベントリスナーを追加しています。

イベントリスナーのコールバック関数として無名関数を使用しています。

クリックされると、アラートが表示されます。

document.getElementById("button").addEventListener("click", function() {
  // この無名関数がボタンがクリックされたときに実行されます
  alert("ボタンがクリックされました。");
});

○サンプルコード2:配列のmapメソッドに無名関数を使う

下記のサンプルコードでは、配列の各要素を二乗する処理を行っています。

配列のmapメソッドに無名関数を渡し、各要素に対して処理を行います。

const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(function(number) {
  // この無名関数が各要素に対して実行され、二乗した値を返します
  return number * number;
});

console.log(squaredNumbers); // [1, 4, 9, 16, 25]

○サンプルコード3:即時実行関数を使う

下記のサンプルコードでは、即時実行関数(Immediately Invoked Function Expression, IIFE)を使用しています。

この関数は定義と同時に実行されます。

この方法は、スコープを限定して変数の競合を防ぐ目的でよく使われます。

(function() {
  // この無名関数が即時実行されます
  const message = "即時実行関数の中です。";
  console.log(message);
})();

○サンプルコード4:クロージャを作成する

下記のサンプルコードでは、無名関数を使ってクロージャを作成しています。

クロージャは、関数とその関数がアクセスできる環境を一緒にキャプチャしたものです。

これにより、関数が定義された環境の変数にアクセスできるようになります。

function createCounter() {
  let count = 0;
  
  // この無名関数がクロージャを形成し、count変数にアクセスできます
  return function() {
    count++;
    console.log(count);
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2

●無名関数の応用例

○サンプルコード5:無名関数を使ったデバウンス関数

下記のサンプルコードでは、無名関数を使ってデバウンス関数を実装しています。

デバウンス関数は、高頻度で発生するイベントを一定時間内に一度だけ実行するように制限するために使用されます。

例えば、リサイズイベントやスクロールイベントなどです。

function debounce(func, wait) {
  let timeout;

  return function() {
    const context = this;
    const args = arguments;

    clearTimeout(timeout);
    timeout = setTimeout(function() {
      // この無名関数がデバウンスされたタイミングで実行されます
      func.apply(context, args);
    }, wait);
  };
}

// 使用例
window.addEventListener("resize", debounce(function() {
  console.log("リサイズイベントが発生しました。");
}, 500));

○サンプルコード6:無名関数を使ったthrottle関数

下記のサンプルコードでは、無名関数を使ってthrottle関数を実装しています。

throttle関数は、一定時間内に関数が複数回実行されないように制限するために使用されます。

例えば、リサイズイベントやスクロールイベントでパフォーマンスを向上させるために使われます。

function throttle(func, wait) {
  let inThrottle, lastFunc, lastTime;

  return function() {
    const context = this;
    const args = arguments;
    const now = new Date().getTime();

    if (!inThrottle) {
      func.apply(context, args);
      lastTime = now;
      inThrottle = true;
    } else {
      clearTimeout(lastFunc);
      lastFunc = setTimeout(function() {
        // この無名関数がthrottleされたタイミングで実行されます
        if (now - lastTime >= wait) {
          func.apply(context, args);
          lastTime = now;
        }
      }, wait - (now - lastTime));
    }
  };
}

// 使用例
window.addEventListener("scroll", throttle(function() {
  console.log("スクロールイベントが発生しました。");
}, 200));

○サンプルコード7:無名関数を使ったプロミスチェイン

下記のサンプルコードでは、無名関数を使ってプロミスチェインを作成しています。

プロミスチェインは、非同期処理の結果に基づいて、次の処理を連鎖的に実行する方法です。

function fetchData() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      // この無名関数が非同期処理が完了したタイミングで実行されます
      resolve("データ取得完了");
    }, 1000);
  });
}

fetchData().then(function(data) {
  console.log(data); // "データ取得完了"
  return "次の処理へ";
}).then(function(nextData) {
  console.log(nextData); // "次の処理へ"
}).catch(function(error) {
  console.error(error);
});

○サンプルコード8:無名関数を使ったオブジェクトリテラル

下記のサンプルコードでは、無名関数を使ってオブジェクトリテラルのメソッドを定義しています。

これにより、オブジェクト内で関数を簡潔に定義できます。

const obj = {
  add: function(a, b) {
    // この無名関数がオブジェクトのメソッドとして実行されます
    return a + b;
  }
};

console.log(obj.add(1, 2)); // 3

○サンプルコード9:無名関数を使った簡易テンプレートエンジン

下記のサンプルコードでは、無名関数を使って簡易テンプレートエンジンを実装しています。

これにより、テンプレート文字列に変数を埋め込んで、動的な文字列を生成することができます。

function template(templateString, data) {
  return templateString.replace(/\${(.*?)}/g, function(_, key) {
    // この無名関数がマッチした部分を置換するために実行されます
    return data[key.trim()] || "";
  });
}

const result = template("こんにちは、${ name }さん。今日は${ weather }ですね。", {
  name: "山田",
  weather: "晴れ"
});

console.log(result); // "こんにちは、山田さん。今日は晴れですね。"

○サンプルコード10:無名関数を使ったカリー化

下記のサンプルコードでは、無名関数を使ってカリー化を実装しています。

カリー化とは、複数の引数を取る関数を、一部の引数を固定した新しい関数に変換することです。

function curry(fn) {
  return function curried(...args) {
    // この無名関数がカリー化された関数を返すために実行されます
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function(...args2) {
        // この無名関数が残りの引数を受け取るために実行されます
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}

function add(a, b, c) {
  return a + b + c;
}

const curriedAdd = curry(add);
const addFive = curriedAdd(5); // 引数aが5に固定された新しい関数が作成されます

console.log(addFive(3, 2)); // 10

●注意点と対処法

無名関数を使用する際の注意点として、次の点が挙げられます。

  1. 無名関数は名前がないため、デバッグ時にエラースタックトレースが追いにくくなることがあります。

    対処法として、名前付き関数を使うか、無名関数に名前を割り当てることができます。

  2. 無名関数の多用により、コードが複雑になることがあります。

    対処法として、適切な名前付き関数にリファクタリングして、コードの可読性を向上させることができます。

まとめ

無名関数は、イベントリスナーやコールバック関数など、一度きりの処理に適しています。

また、即時実行関数やクロージャ、デバウンス関数、カリー化など、さまざまな応用例が存在します。

ただし、無名関数の使用には注意点もありますので、適切な方法で対処することが重要です。