Skip to content

Commit

Permalink
finish writing IIFE page.
Browse files Browse the repository at this point in the history
  • Loading branch information
takezoux2 committed Oct 9, 2023
1 parent 62419c5 commit 429377b
Showing 1 changed file with 40 additions and 12 deletions.
52 changes: 40 additions & 12 deletions docs/reference/functions/iife.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
sidebar_label: "即時実行関数"
sidebar_label: "即時実行関数式(IIFE)"
---

# 即時実行関数 (IIFE)
# 即時実行関数式 (IIFE)

IIFE (Immediately Invoked Function Expression; 即時実行関数式) とは定義と同時に実行される関数です。
デザインパターンの1種で、Self-Executing Anonymous Function; 自己実行匿名関数とも呼ばれます。

次のように定義します
TypeScriptにおいては、次のように定義、使用します

```typescript
(() => {
Expand All @@ -24,13 +25,15 @@ const result2 = await(async () => {
})();
```

## TypeScriptでの使用パターン
## TypeScriptでの利用シーン

### ReactのuseEffectなど、非同期関数を受け取らない引数に非同期処理を渡したい場合

ReactのuseEffectなど、非同期関数を受け取らない引数に非同期処理を渡したい場合、即時実行関数を使うことで、非同期処理を引数に渡すことができます。

```typescript
```ts twoslash
function useEffect(f: () => void, args: string[]) {}
// ---cut---
useEffect(() => {
(async () => {
const result = await fetch("https://example.com");
Expand All @@ -41,43 +44,47 @@ useEffect(() => {

ただし、実行は非同期で実行されることに注意してください。戻り値としてvoidではなく、何らかの具体値を返す関数には適用できません。

```typescript
```ts twoslash
// @errors: 2322
function receivesSyncFunc(func: () => string) {
console.log(func());
}

// NG
receivesSyncFunc(() => {
(async () => {
receivesSyncFunc((): string => {
// Promise<string>が戻り値となってしまい、利用不可
return (async () => {
return "hoge";
})();
});
```

### ifやswitchなどを式として扱いたい場合

次のように使用します。
TypeScriptでのifやswitchは構文であり式ではないため、判定結果を変数に代入することができません。そのため、疑似的にifやswitchを式として扱うときにIIEFを利用できます。<br />
また、ifやswitchの条件判定が複雑になった場合に、判定に利用する変数や、どこまでが判定処理かを明確にできるため可読性が向上します。

```typescript
const result = (() => {
const result = ((type: string) => {
if (type === "Apple") {
return "林檎";
} else if (type === "Orange") {
return "オレンジ";
} else {
return "謎の果物";
}
})();
})(fruit.type);
```

もしIIFEを使わない場合は次のような実装となります。

```typescript
let result;
const type = fruit.type;
if (type === "Apple") {
result = "林檎";
} else if (type === "Orange") {
result = "オレンジ";
result = "蜜柑";
} else {
result = "謎の果物";
}
Expand All @@ -87,6 +94,27 @@ if (type === "Apple") {

### スコープ内での変数汚染を防ぐ

汎用的な変数の場合、同じスコープ内で複数回使いたい場合があるかと思います。
その際に、IIFEを利用することで変数名のスコープを限定し名前の重複を回避できます。

```typescript
async function callApiAAndB() {
await (async () => {
const result = await fetch("api1");
if (result !== "OK") {
console.log(result);
}
})();
await (async () => {
const result = await fetch("api2");
if (result !== "Success") {
console.log(result);
}
})();
}
```

## 参考

[MDN - IIFE (即時実行関数式)](https://developer.mozilla.org/ja/docs/Glossary/IIFE)
[MDN Self-Executing Anonymous Function](https://developer.mozilla.org/ja/docs/Glossary/Self-Executing_Anonymous_Function)

0 comments on commit 429377b

Please sign in to comment.