How Lodash Handles Conflicting Getters in Merges

When merging objects with identically named getters, the Lodash library resolves conflicts by evaluating the getters into static values and applying a last-write-wins strategy. Rather than transferring the underlying getter functions or property descriptors, Lodash executes them during traversal, merges the returned data, and assigns the final evaluated result as a standard value property on the destination object.

Immediate Getter Invocation

When _.merge processes source objects, it accesses properties using standard property lookup rather than inspecting property descriptors via Object.getOwnPropertyDescriptor. This means that as soon as Lodash reads a property backed by a getter, JavaScript invokes the getter function immediately. Lodash receives only the returned value of the getter, entirely unaware that the property was originally an accessor.

Precedence and Conflict Resolution

When multiple source objects define a getter with the same key, Lodash processes them sequentially from left to right:

Loss of Accessor Descriptors

Because Lodash copies evaluated values rather than property descriptors, the target object loses the dynamic nature of the original getters. After the merge is complete, the resulting property becomes a standard, writable, and configurable data property containing the final merged value. Any subsequent state changes that would have altered the original getter's return value will no longer reflect on the merged object.

Custom Conflict Resolution with _.mergeWith

If default evaluation or overwriting behavior is undesirable, Lodash provides the _.mergeWith method. This function accepts a customizer callback that exposes the target value, source value, property key, and parent objects:

const _ = require('lodash');

const objA = {
  get value() { return { a: 1 }; }
};

const objB = {
  get value() { return { b: 2 }; }
};

const result = _.mergeWith({}, objA, objB, (objValue, srcValue, key) => {
  // Custom logic to handle specific keys or retain descriptors
  if (key === 'value') {
    return Object.assign({}, objValue, srcValue);
  }
});

Using _.mergeWith allows developers to intercept the conflict and determine whether to combine, prioritize, or conditionally preserve values before Lodash applies its default recursive assignment.