Closures and Event Handlers

Event handlers commonly use closures to retain component state or configuration across later events. A closure lets a function keep access to variables from its surrounding lexical scope even after that outer function has finished.

A closure is created when a function uses variables from an enclosing scope. The function retains access to those variables through its lexical environment, so the values can remain available when the function runs later.

This is especially useful for event handlers. When you register a handler such as `button.addEventListener('click', handler)`, the browser can call `handler` much later, while the handler can still access variables that were in scope when it was created.

Closures are useful for associating configuration or state with a particular handler. For example, a factory function can create handlers that each remember a different label or identifier without storing that information in a global variable.

In frontend code, closures also appear in timers, subscriptions, callbacks, and framework event handlers. The important distinction is that a closure captures access to variables, not necessarily a frozen copy of their values; if the captured variable is later changed, the handler can observe the updated value.

Key points

Interview questions

What problem can closures cause with event listeners in frontend applications?

A closure can keep references to objects that the handler uses, which may keep those objects reachable longer than intended. Event listeners can also become difficult to remove if code creates a new function instead of retaining the original handler reference. In long-lived applications, unnecessary listeners and captured data can therefore contribute to memory or lifecycle problems.

What is a closure, and why are closures useful in event handlers?

A closure is a function together with access to variables from its surrounding lexical scope. An event handler often runs after the code that registered it has finished, but the handler can still access those captured variables. This makes closures useful for retaining configuration or state associated with a particular event handler.

Does a closure capture a value or a variable?

Conceptually, a closure retains access to the variable binding from its surrounding lexical environment. Therefore, if that binding is changed before the handler runs, the handler can observe the changed value. This differs from assuming that every closure automatically stores an immutable snapshot.

How can you create multiple event handlers that remember different values?

A common pattern is to use a factory function that creates and returns a handler. Each call to the factory creates a new lexical environment, so the returned handlers can close over different values. Registering those handlers with different elements or events keeps the associated configuration separate.