即時実行関数式

出典: フリー百科事典『ウィキペディア(Wikipedia)』

即時実行関数式(そくじじっこうかんすうしき、: immediately invoked function expression[1]IIFE)は、プログラミング言語において、関数を定義後、即座に実行するような構文のこと。そのような関数を指して即時実行関数即時関数などと呼ぶこともある。

構文[編集]

JavaScriptでの例を下記に示す。

// ①
(function sum(a, b, c) {
    return a + b + c;
})(2, 3, 5);

// ②
(function () {
    return 1 + 2;
})();

①の例では、引数のあるsum関数を定義後、即座に引数を与えて評価している。②の場合は、引数なしの無名関数を定義した後、それを直ちに呼び出して評価している(自己実行無名関数)。
これらの関数は、定義・実行前後で再度参照することは出来ず、①のように関数名を付与する意味合いは薄い。余計な関数名を考える必要が無くなるというのも利点であるため、単に即時実行関数といった場合、②のような無名関数を指すことがほとんどである。
上記どちらの例でも、名前の通りであるので、戻り値の変数への代入が可能である。

// ①
const x = (function sum(a, b, c) {
    return a + b + c;
})(2, 3, 5);

// ②
const y = (function () {
    return 1 + 2;
})();

console.log(x, y); // 10 3

これらの式は、関数が再利用可能かなどの点を除けば、下記と実質的に同じである。

// ①
const sum = function sum(a, b, c) {
    return a + b + c;
}
const x = sum(2, 3, 5);

// ②
const doAddition = function () {
    return 1 + 2;
}
const y = doAddition();

console.log(x, y); // 10 3

使用例[編集]

  • ifswitchforなど、としてしか扱えない処理の結果を、一時変数を(同一スコープに)用意することなく取得することもできる。
    /** 非負の整数 */
    const int = 3;
    
    /** `int`が奇数か偶数かを判定した結果 */
    const oddOrEven = (() => {
        if (int < 0) {
            return "非負数ではありません";
        }
        
        switch (int % 2) {
            case 0:
                return "偶数です";
            case 1:
                return "奇数です";
            default:
                return "整数ではありません";
        }
    })();
    
    console.log(`${int}${oddOrEven}`); // 3 は奇数です
    
    /**
     * ページ内の全チェックボックスのリスト
     * @type {NodeListOf<HTMLInputElement>}
     */
    const checkboxes = document.querySelectorAll("input[type=checkbox]");
    
    /**
     * ページ内の全チェックボックスのうち、チェックが入っているものの個数
     * @type {number}
     */
    const numOfChecked = (() => {
        // `let count`を即時実行関数内で定義することで、スコープを限定することができる
        let count = 0;
        
        for (const checkbox of checkboxes) {
            if (checkbox.checked) count++;
        }
        
        return count;
    })();
    
    console.log(count); // ReferenceError: count is not defined
    
  • ReactuseEffectなどは、第一引数として、関数(クリーンアップ関数)またはundefinedを返すような関数を指定する必要があり、非同期関数を渡すことができない(戻り値が Promise となるため)。この場合、渡したい非同期関数を即時実行関数とすることで、この問題を解消することができる[2]
    import { useEffect } from "react";
    
    // エラーが出る例:
    const BadExapmleComponent = () => {
        // Warning: useEffect must not return anything besides a function, which is used for clean-up.
        useEffect(async () => {
            await fetch("https://api.example.com/");
        }, []); 
        
        return (
            <div>
                {/* ... */}
            </div>
        );
    };
    
    // 即時実行関数を使用した例:
    const GoodExampleComponent = () => {
        // useEffect に渡す関数の内部で、async function を即時実行関数として定義している
        // マウント時に外側の関数が呼び出されることで、その内部にある async function も(即時実行関数としているため)実行される
        useEffect(() => {
            (async () => {
                await fetch("https://api.example.com/");
            })();
        }, []); 
        
        return (
            <div>
                {/* ... */}
            </div>
        );
    };
    

脚注[編集]

  1. ^ IIFE (即時実行関数式) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN” (英語). developer.mozilla.org (2023年11月24日). 2024年2月26日閲覧。
  2. ^ 即時実行関数式 (IIFE) | TypeScript入門『サバイバルTypeScript』”. typescriptbook.jp. 2024年2月28日閲覧。