Lodash rearg With Indices Exceeding Arity

This article explores how Lodash’s _.rearg utility behaves when configured with index mappings that significantly exceed a target function's native arity or the number of arguments supplied at call time. It details the runtime resolution of out-of-bounds indices, JavaScript's permissive argument handling, and the practical implications for function execution.

Mechanism of _.rearg

The _.rearg method creates a wrapper function that rearranges incoming arguments according to an array of specified index positions. Each element in the index array dictates which incoming argument index should be placed into that position for the underlying target function.

Under the hood, Lodash iterates through the mapping array and looks up values from the incoming arguments list:

var resultArgs = indexes.map(index => providedArgs[index]);

Because this mapping relies on standard JavaScript property access, supplying indices that exceed native arity or actual argument length produces deterministic behavior governed by standard language semantics rather than library-level errors.

Indices Exceeding Provided Arguments

When an index in the mapping array references an argument position that the caller did not supply, JavaScript evaluates the out-of-bounds array access to undefined.

For example:

const fn = (a, b) => [a, b];
const rearged = _.rearg(fn, [100, 200]);

rearged('first', 'second');
// Result: [undefined, undefined]

Lodash does not validate whether a requested index exists within the runtime arguments list. The mapped argument list simply receives undefined at those positions and forwards them directly to the target function.

Indices Exceeding Declared Arity (func.length)

JavaScript functions do not restrict invocation to their declared parameter count (func.length). If the index array itself contains more elements than the function's formal parameters, _.rearg forwards all mapped arguments regardless of the function's native arity.

Consider the following scenario:

function sum(a, b) {
  // sum.length is 2
  return a + b;
}

const rearged = _.rearg(sum, [0, 1, 2, 3, 4]);
rearged(10, 20, 30, 40, 50);

In this case:

  1. The mapping array length is 5, while sum.length is 2.
  2. The wrapper constructs an argument payload of length 5: [10, 20, 30, 40, 50].
  3. The underlying sum function receives all five arguments. a binds to 10, b binds to 20, and the remaining three arguments are silently accepted without triggering an error.

The extra arguments can still be read inside the target function using rest parameters ((...rest) => ...) or the legacy arguments object.

Summary of Runtime Impact

Supplying excessively high index mappings to _.rearg produces two main effects: