How Lodash _.once Guarantees Single Execution

The Lodash _.once method guarantees that a specified function is invoked only once by wrapping it within a closure that tracks execution state and caches the output. This article explains the internal mechanics behind this behavior, detailing how _.once utilizes higher-order functions, manages internal invocation counters, and recycles references to prevent redundant executions and optimize memory usage.

The Underlying Delegation to _.before

In the Lodash source code, _.once(func) does not implement standalone logic from scratch. Instead, it is a direct alias for _.before(2, func). The _.before method creates a wrapper function that allows the target function to be invoked up to \(n - 1\) times. By passing 2 as the threshold argument, Lodash restricts execution strictly to a single time (\(2 - 1 = 1\)).

State Management via Closures

When _.once is called, it creates a closure containing three critical private variables:

  1. func: A reference to the original function passed into _.once.
  2. n: A counter initialized to the threshold (in this case, 2).
  3. result: A variable reserved to store the return value of the initial execution.

Because these variables live in the lexical environment of the wrapper, they persist across multiple calls to the generated function without leaking into the global scope.

The Execution and Mutation Phase

When the wrapped function is called for the first time:

  1. Threshold Check and Decrement: Lodash checks if n is greater than 0. Because n begins at 2, the check succeeds, and n is decremented to 1.
  2. Invocation: Because n <= 1 now evaluates to true, the wrapper invokes the original func using func.apply(this, arguments), capturing the provided this binding and arguments.
  3. Result Caching: The returned value from the invocation is assigned to the closure's result variable.
  4. Reference Cleanup: To allow garbage collection and prevent subsequent executions, the internal func variable is explicitly set to undefined once n <= 1.

Handling Subsequent Invocations

On the second and any subsequent calls:

  1. The wrapper again checks the counter condition. Since n was decremented to 1 during the first run, the invocation condition fails.
  2. The original function is never called again. If an attempt were somehow made, func is now undefined.
  3. The wrapper immediately skips execution and returns the stored result.

Simplified Implementation Example

The core logic of Lodash's approach can be represented in pure JavaScript as follows:

function once(func) {
  let result;
  let called = false;

  return function(...args) {
    if (!called) {
      called = true;
      result = func.apply(this, args);
      func = null; // Free reference for garbage collection
    }
    return result;
  };
}

Through this combination of closures, explicit invocation bounds, and reference clearing, Lodash ensures deterministic single execution while consistently returning the initial result on all subsequent calls.