Lodash invokeMap with Path Array Method Names
The _.invokeMap method in Lodash allows developers to
invoke a specific function on each element in a collection, returning
the results in a new array. When the method target is defined as an
array of path segments rather than a simple string, Lodash traverses
nested object structures to locate the method, properly preserves the
execution context (this), passes any provided arguments,
and gracefully handles missing properties along the path.
Path Normalization and Traversal
When you pass an array of path segments (such as
['nested', 'deeply', 'methodName']) to
_.invokeMap, Lodash routes the operation through internal
helpers, primarily baseEach and
baseInvoke.
For each item in the collection, Lodash processes the segment array using these steps:
- Path Division: Lodash identifies the path to the
parent object by taking all segments except the last one (using
lastandinitialslices). For example,['a', 'b', 'c']is divided into a parent path['a', 'b']and the target method name'c'. - Parent Resolution: Using internal navigation logic
identical to
_.get, Lodash walks through the object using the parent path segments. If the path array contains only a single element (e.g.,['methodName']), the current collection item itself is treated as the parent object. - Method Retrieval: Lodash accesses the property corresponding to the final segment on the resolved parent object.
Context Preservation and Execution
A critical aspect of providing a path array is preserving the
this binding. In JavaScript, invoking an extracted nested
function without explicit binding can cause this to default
to undefined or the global object.
Lodash handles this automatically:
- If the method at the resolved path is a function, Lodash executes it
using standard Function application:
func.apply(parent, args). - Setting
parentas the execution context ensures that the method has access to sibling properties on its immediate enclosing object. - Any additional arguments provided to
_.invokeMap(collection, path, ...args)are passed directly to the function call.
Safe Navigation and Guarding
If any segment along the path array does not exist, or if the
resolved property is not a callable function, Lodash does not throw a
TypeError. Instead, it guards the invocation:
- If navigating the path yields
nullorundefinedat any intermediate step, traversal stops. - If the final resolved property is missing or not a function, Lodash
yields
undefinedfor that collection item.
Example
const _ = require('lodash');
const users = [
{
profile: {
getName(prefix) {
return `${prefix} ${this.firstName}`;
},
firstName: 'Alice'
}
},
{
profile: {
getName(prefix) {
return `${prefix} ${this.firstName}`;
},
firstName: 'Bob'
}
},
{
// Missing 'profile' branch
name: 'Charlie'
}
];
// Invoking using a path segment array
const results = _.invokeMap(users, ['profile', 'getName'], 'User:');
console.log(results);
// Output: ['User: Alice', 'User: Bob', undefined]In this execution, Lodash navigates to item.profile for
each entry, evaluates getName, binds this to
item.profile, and passes 'User:' as the
argument, safely returning undefined for the entry lacking
the nested path.