How Lodash rest Collects Trailing Arguments

The Lodash _.rest method is a higher-order function designed to collect trailing arguments into a single array before passing them to a target function. By default, it captures all arguments beginning from the target function's final declared parameter, enabling flexible argument handling without relying on the legacy arguments object or requiring native ES6 rest syntax.

How the Method Works Internally

The _.rest function takes two parameters: the target function (func) and an optional index representing where collection should begin (start).

_.rest(func, [start=func.length - 1])

When _.rest is invoked, it returns a new wrapper function. The argument collection process follows these direct steps:

  1. Determining the Start Index: If a start index is not explicitly provided, Lodash calculates it based on the arity of the function (func.length - 1). The parameter at this index will hold the collected array.
  2. Separating Leading Arguments: When the wrapped function is called, Lodash extracts the arguments that precede the start index. These arguments are preserved as individual, positional parameters.
  3. Collecting Trailing Arguments: All arguments received at or beyond the start index are sliced and accumulated into a standard JavaScript array. If no arguments are provided past the start index, an empty array is used.
  4. Invocation: The wrapper calls the original function using the caller's this binding, passing the leading individual parameters followed by the newly constructed rest array.

Practical Implementation

In practice, _.rest eliminates the need to manually slice the arguments object inside a function body.

const _ = require('lodash');

const buildMessage = _.rest(function(header, tags) {
  return `${header}: [${tags.join(', ')}]`;
});

// Calling the function with trailing arguments
buildMessage('Status', 'urgent', 'bug', 'backend');
// Output: "Status: [urgent, bug, backend]"

In this example:

Customizing the Collection Point

The start parameter allows you to override the default arity-based behavior. If you want collection to begin earlier or later than the final parameter, pass a explicit numeric index:

const aggregate = _.rest(function(allArgs) {
  return allArgs;
}, 0);

aggregate(1, 2, 3, 4);
// Output: [1, 2, 3, 4]

By specifying 0, every argument supplied to aggregate is collected directly into the allArgs array.

Comparison to Native Rest Parameters

While the native ES6 rest syntax (...args) accomplishes a similar outcome at the language level, _.rest provides two distinct advantages in certain codebases: