How Lodash forOwnRight Iterates Object Keys in Reverse

Lodash’s _.forOwnRight method iterates over an object's own enumerable string-keyed properties in reverse order compared to standard iteration methods like _.forOwn. While traditional loops and methods process properties from first to last based on property definition order, _.forOwnRight reverses the traversal sequence, evaluating keys from the "right" (end) to the "left" (beginning). This behavior is particularly useful for workflows that require Last-In, First-Out (LIFO) processing, mutating objects safely during traversal, or finding and stopping at the last matching property.

The Mechanism Behind Reverse Traversal

Under the hood, _.forOwnRight obtains the list of an object's own enumerable properties—similar to calling Object.keys()—and iterates through this list starting at the highest index (array.length - 1) and counting down to 0.

The callback (iteratee) function receives three arguments for each step:

  1. value: The value of the current property.
  2. key: The key of the current property.
  3. object: The source object being traversed.

Unlike _.forInRight, which traverses inherited prototype properties as well, _.forOwnRight strictly targets the object's own properties.

Standard vs. Reverse Iteration Example

Consider an object with sequentially added properties:

const _ = require('lodash');

const config = {
  first: 1,
  second: 2,
  third: 3
};

// Standard forward iteration
_.forOwn(config, (value, key) => {
  console.log(key, value);
});
// Output:
// 'first' 1
// 'second' 2
// 'third' 3

// Reverse iteration with forOwnRight
_.forOwnRight(config, (value, key) => {
  console.log(key, value);
});
// Output:
// 'third' 3
// 'second' 2
// 'first' 1

Key Ordering Nuances with Integers

JavaScript objects follow deterministic property traversal rules defined by ECMAScript:

  1. Non-negative integer-like keys appear first, sorted in ascending numeric order.
  2. String keys appear next, sorted in chronological insertion order.
  3. Symbol keys appear last, sorted in chronological insertion order.

_.forOwnRight does not alter these internal JavaScript groupings; rather, it takes the final ordered list of keys generated according to the specification and reverses that exact sequence.

const items = {
  b: 'letter B',
  2: 'number two',
  a: 'letter A',
  1: 'number one'
};

// Standard order would be: '1', '2', 'b', 'a'
_.forOwnRight(items, (value, key) => {
  console.log(key);
});
// Output:
// 'a'
// 'b'
// '2'
// '1'

Early Termination

Just like _.forOwn, _.forOwnRight allows early termination of the loop. If the iteratee explicitly returns false, iteration stops immediately:

const records = {
  stepA: 'pending',
  stepB: 'completed',
  stepC: 'pending'
};

_.forOwnRight(records, (status, step) => {
  console.log(`Checking ${step}`);
  if (status === 'completed') {
    console.log(`Most recent completed step: ${step}`);
    return false; // Halts further iteration
  }
});
// Output:
// 'Checking stepC'
// 'Checking stepB'
// 'Most recent completed step: stepB'

By beginning from the end of the property list, _.forOwnRight simplifies scenarios where the latest-defined properties take precedence over earlier ones.