An immediately invoked function expression (IIFE) defines and executes a function at once. Its function scope houses variables and behavior, exposing selected values while hiding private data. Before native modules, this pattern provided practical modularity, avoided global-name clashes, and remains useful for small applications and scripts, including older-browser targets. section 6.2 section 6.2.2
Listing 6.4 Using an IIFE
(function Transaction(namespace) {
const VERSION = '1.0'; #1
namespace.domain = {}; #2
namespace.domain.Transaction = class { #3
#feePercent = 0.6;
constructor(sender, recipient, funds = 0.0) {
this.sender = sender;
this.recipient = recipient;
this.funds = Number(funds);
this.timestamp = Date.now();
this.transactionId = calculateHash ( #4
[this.sender, this.recipient, this.funds].join()
);
}
...
}
function calculateHash(data) { #5
...
}
})(global.BlockchainApp || (global.BlockchainApp = {})); #6
Uses a Transaction IIFE to create a namespace, keep VERSION and calculateHash private, and expose a Transaction class through BlockchainApp.domain. section 6.2.2
Apply the pattern in several closely related ways:
- Create an object namespace inside the IIFE, then expose only the public domain objects needed by callers. section 6.2.2
- Wrap a mixin in an IIFE and use Function#call or Function#apply to extend a target object without exposing the enhancement process. section 6.2.3
- Use an immediately invoked async function expression when asynchronous startup work must run before top-level await is available. section 8.6
- Prefer ECMAScript Modules when static dependency management, dead-code elimination, tree-shaking, or top-level await is appropriate. section 6.6 section 8.6
Immediate asynchronous initialization
An async IIFE creates an async context, awaits a dynamic import, and starts execution immediately: (async () => { await import(...); })();. In an ECMAScript Module, top-level await can replace this wrapper. section 8.6


