JavaScript安全代码与全局执行上下文:IIFE为何可处理异步事件?
Great question—this trips up a lot of folks when they first learn about JavaScript execution contexts and closures! Let's break this down clearly.
First, let's confirm the basics: when your IIFE (function(){ ... })() runs, it does get pushed onto the call stack, execute its code, and then pop off the stack once it's done. But here's the key piece you're missing: closures.
What's a Closure, and How Does It Apply Here?
A closure is when an inner function retains access to variables from its outer function's scope—even after the outer function has finished executing.
In your example:
(function(){ // All data var a=true; btn.addEventListener("click",()=>{ alert(a); }); })()
When the IIFE runs, it creates a local variable a and attaches a click event listener to btn. The arrow function you pass as the callback is an inner function, and it references the variable a from the IIFE's scope.
JavaScript's garbage collector doesn't clean up the IIFE's scope after the function exits because the callback function still has an active reference to that scope. The scope is kept alive specifically so the callback can access a later.
How the Asynchronous Click Fits In
Click events are asynchronous—they don't run immediately. When the user clicks the button later, the browser adds the callback function to the JavaScript event loop's task queue. Once the main thread is free, the callback is pulled from the queue and executed.
When that callback runs, it still has access to the closed-over scope from the IIFE, so it can grab the value of a and show the alert just like you'd expect.
Why This Is So Useful
This is exactly why frameworks use IIFEs: they get to keep all their variables isolated in a local scope (avoiding global name collisions) while still being able to set up event listeners, timers, or other asynchronous operations that need to access those variables later.
内容的提问来源于stack exchange,提问作者Mohan Pierce

