How Lodash _.method Resolves and Invokes Paths

Lodash’s _.method utility creates a function that invokes the method located at a specified path of a given target object, applying any supplied arguments. Internally, Lodash achieves this by standardizing the target path, traversing the object tree to isolate the terminal property and its execution context, and executing the resolved function using native function invocation mechanics. This article breaks down the internal lifecycle of _.method, tracing its execution flow from path parsing to context-bound execution.

Creation via Function Currying

Calling _.method(path, ...args) does not immediately run a function against an object; instead, it acts as a higher-order function factory. It returns an anonymous closure designed to accept an incoming target object:

function method(path, ...args) {
  return function(object) {
    return baseInvoke(object, path, args);
  };
}

The returned function captures both the path definition and any partially applied args in its scope, deferring actual execution until the resulting function is invoked with a concrete object.

Path Normalization (castPath and toPath)

When the generated function receives an object, Lodash delegates processing to an internal function typically referred to as baseInvoke. The first critical step is converting the path into a predictable format.

Paths passed to _.method can take various forms, such as string dot-notation ("a.b.c"), bracket notation ("a[0].b"), or arrays of keys (['a', 0, 'b']). Lodash normalizes these representations through internal helpers like castPath and stringToPath:

  1. Type Checking: If the path is already an array, it is preserved.
  2. Key Conversion: If the path is a string containing delimiters, it is parsed via regular expressions into an array of property identifiers.
  3. Symbol Support: JavaScript symbols and non-delimited property keys are preserved without string splitting.

This step produces a linear array of keys representing each step in the object hierarchy.

Context Traversal (parent Resolution)

For a method to execute correctly in JavaScript, it must preserve its binding to the parent object (this context). Simply retrieving the function reference and calling it would strip the method of its object context, leading to broken internal references or runtime errors.

Lodash handles this by splitting the normalized path into two distinct parts:

Internally, Lodash traverses the object tree down to the parent segment using logic equivalent to baseGet. If any intermediate property evaluates to null or undefined, the traversal safely aborts, returning undefined rather than throwing a reference error.

Safe Function Invocation

Once the parent object and the target method key are isolated, Lodash verifies that the target property is actually callable:

  1. Lookup: The function is accessed directly from the resolved parent context: const func = parent == null ? undefined : parent[toKey(lastSegment)].
  2. Validation: Lodash checks whether func is a callable function.
  3. Dispatch: If callable, Lodash invokes the method using the native apply mechanism:
return func == null ? undefined : func.apply(parent, args);

By passing parent as the first argument to .apply(), Lodash ensures that the invoked function receives the correct this reference. The arguments supplied during the initial _.method declaration are unpacked directly into this call.

Through this sequence—path normalization, safe parent traversal, context mapping, and guarded application—_.method provides a declarative, safe way to map object paths directly to method invocations.