QuestionsJavaScript

once() — invoke a function at most once

Higher-Order FunctionsMediumJavaScript

Write once(fn) that returns a wrapper calling fn only the first time; subsequent calls return the first result without re-invoking.

What it tests

Closure over a 'called' flag + cached value, and preserving this/args on that first call.

Approach & answer

once is a higher-order function that enforces single execution — the classic use is idempotent initialisation (set up a connection, attach a one-time handler, run an expensive bootstrap exactly once no matter how many callers fire it). The implementation is a closure capturing two private variables: a boolean flag (has it run?) and the cached return value. The returned wrapper checks the flag; on the FIRST call it invokes fn — using `fn.apply(this, args)` so the wrapper transparently forwards both the receiver and all arguments — stores the result, flips the flag, and returns it; on every later call it skips fn entirely and returns the cached value. Preserving `this` matters so `obj.method = once(fn)` still binds correctly. This differs from memoize (js-10): memoize caches PER distinct-arguments key and may call fn many times for different inputs; once ignores arguments after the first call and never invokes fn again regardless of input. It's the runtime analogue of a lazy singleton. A common refinement is to release the reference to fn after the first call (set it to null) so any large closure it captured can be garbage-collected.

Use this technique when

One-time setup/initialisation, guarding event handlers that must fire once, and building lazy singletons.

Complexity

O(1) per call after the first.

References

js