notes

Log | Files | Refs | README

iife.md (2632B)


      1 # Immediately Invoked Function Expression (IIFE) in TypeScript
      2 
      3 An **IIFE** (immediately invoked function expression) is a function that is
      4 defined and executed in the same statement. The pattern has been part of
      5 JavaScript since the language’s early use in the browser, where it was a
      6 practical way to create a **local scope** and **avoid polluting the global
      7 object** when true modules were not available.
      8 
      9 ## Basic shape
     10 
     11 The function is wrapped in parentheses so the parser treats it as an
     12 expression, then it is called with `()`:
     13 
     14 ```ts
     15 (function () {
     16   const secret = 42
     17   // `secret` is not visible outside this function
     18 })()
     19 ```
     20 
     21 With an arrow function, a similar effect is common in modern code:
     22 
     23 ```ts
     24 ;(() => {
     25   // one-off setup or isolated block
     26 })()
     27 ```
     28 
     29 A leading semicolon (or a line break before `(`) avoids the rare case where
     30 the previous line’s expression is parsed as a function call.
     31 
     32 ## Why it still matters in TypeScript
     33 
     34 1. **Encapsulation** — `const` and `let` inside the IIFE are not hoisted to
     35    an outer scope, so you can run initialization logic without exporting
     36    implementation details. With ES modules, file scope already provides
     37    privacy for top-level declarations, so IIFEs are less about “hiding from
     38    globals” and more about **grouping** one-time work or **avoiding name
     39    clashes** in a single file with many top-level symbols.
     40 
     41 2. **Async IIFE** — `async` functions return a `Promise`. Invoking one
     42    immediately is a standard way to use `await` at the top level inside a
     43    context that does not allow top-level `await` (older bundlers or scripts),
     44    or to fire-and-forget async setup while keeping the rest of the module
     45    synchronous:
     46 
     47    ```ts
     48    ;(async () => {
     49      await someSetup()
     50    })()
     51    ```
     52 
     53    In modern ES modules with **top-level await** enabled, you can often
     54    replace this with plain `await` at module scope.
     55 
     56 3. **Return values** — An IIFE can produce a value that you assign or export:
     57 
     58    ```ts
     59    export const config = (() => {
     60      const raw = process.env["FEATURE"]
     61      return raw === "on"
     62    })()
     63    ```
     64 
     65 ## Trade-offs
     66 
     67 IIFEs add nesting and can make stack traces slightly noisier. Prefer **small
     68 named functions** or **plain module-level code** when there is no need for an
     69 extra scope. Use an IIFE when you want a **single expression** that computes a
     70 value with private locals, or when you need **async execution** without making
     71 the whole module async.
     72 
     73 ## References
     74 
     75 - [MDN: IIFE](https://developer.mozilla.org/en-US/docs/Glossary/IIFE)
     76 - [TypeScript Handbook — Modules](https://www.typescriptlang.org/docs/handbook/modules.html)