即時実行関数式

**即時実行関数式**（そくじじっこうかんすうしき、**'、**IIFE**）は、[[プログラミング言語]]において、[[第一級関数|関数]]を定義後、即座に実行するような構文のこと。そのような関数を指して**即時実行関数**や**即時関数**などと呼ぶこともある。

== 構文 ==
[[JavaScript]]での例を下記に示す。<syntaxhighlight lang="javascript" line="1">
// ①
(function sum(a, b, c) {
    return a + b + c;
})(2, 3, 5);

// ②
(function () {
    return 1 + 2;
})();
</syntaxhighlight>①の例では、引数のある<code>sum</code>関数を定義後、即座に引数を与えて評価している。②の場合は、引数なしの[[無名関数]]を定義した後、それを直ちに呼び出して評価している（**自己実行無名関数'''）。これらの関数は、定義・実行前後で再度参照することは出来ず、①のように関数名を付与する意味合いは薄い（再帰呼び出しを行う場合などを除く）。余計な関数名を考える必要が無くなるというのも利点であるため、単に即時実行関数といった場合、②のような無名関数を指すことがほとんどである。上記どちらの例でも、名前の通り式であるので、戻り値の変数への代入が可能である。
```javascript
// ①
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
```
これらの式は、関数が再利用可能かなどの点を除けば、下記と実質的に同じである。
```javascript
// ①
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
```


### 使用例
* `if`や`switch`、`for`など、文としてしか扱えない処理の結果を、一時変数を（同一スコープに）用意することなく取得することもできる。
```javascript
/** 非負の整数 */
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 は奇数です
```

```javascript
/**
 * ページ内の全チェックボックスのリスト
 * @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
```

*ECMAScript 5 以前の仕様では、変数宣言は`var`のみであった。`var`で宣言された変数はグローバルもしくは関数スコープのいずれかとなり、即時実行関数を使用することでグローバルスコープの汚染や意図しない変数の再代入を防げる、という利点もあった。
```javascript
// 意図しないスコープ汚染・再宣言が発生するケース
var x = 6, y = 2;

if (x >= 0 && y >= 0) {
    // 割り算の商を求める
    var quot = x / y;     // この quot はグローバルに参照可能
    var isFinite = y > 0; // グローバルの isFinite 関数を上書きしてしまっている
    console.log(isFinite ? quot : "0 で割ることはできません"); // 3
}

console.log(typeof isFinite); // "boolean"
console.log(quot);            // 3
```

```javascript
// 即時関数を用いたケース
var x = 6, y = 2;

(function (x, y) {
    if (x >= 0 && y >= 0) {
        // 割り算の商を求める
        var quot = x / y;     // この quot は関数外から参照不可
        var isFinite = y > 0; // グローバルの isFinite とは異なる変数として宣言される
        console.log(isFinite ? quot : "0 で割ることはできません"); // 3
    }
})(x, y);

console.log(typeof isFinite); // "function"
console.log(quot);            // ReferenceError: quot is not defined
```

* React の`useEffect`などは、第一引数として、関数（クリーンアップ関数）または`undefined`を返すような関数を指定する必要があり、非同期関数を渡すことができない（戻り値が Promise となるため）。この場合、渡したい非同期関数を即時実行関数とすることで、この問題を解消することができる。
```jsx
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>
    );
};
```


## 脚注