Lodash assignIn and Prototype Chain Inheritance

This article examines the exact mechanics of Lodash’s _.assignIn (also known as _.extend) when transferring properties from deeply nested prototype chains to a target object. It details the specific categories of properties that are copied—such as enumerable string-keyed properties—as well as those that are excluded, including Symbols, non-enumerable descriptors, and uninvoked accessors.

Enumerable String-Keyed Properties

_.assignIn iterates over both own and inherited properties of source objects. Across a deep prototype chain, it transfers only enumerable, string-keyed properties.

Under the hood, _.assignIn uses Lodash's internal keysIn operation, which mimics the behavior of a standard JavaScript for...in loop. Any property defined along the prototype chain that has its enumerable attribute set to true is extracted and copied to the target object as an own property.

Excluded Properties

When traversing prototype chains, _.assignIn deliberately ignores several types of properties:

Prototype Shadowing and Resolution Order

When the same property name exists at multiple levels of a deep prototype chain, _.assignIn honors JavaScript's standard prototype shadowing rules:

  1. Properties found closest to the source instance take precedence over properties higher up in the chain.
  2. If an instance defines an own property x, and its prototype also defines x, the value on the instance is the one assigned to the target.
  3. If multiple source objects are supplied to _.assignIn(target, source1, source2), subsequent sources overwrite properties set by earlier sources.

Value Evaluation and Accessors

_.assignIn performs an assignment ([[Set]]) rather than a property descriptor definition ([[DefineOwnProperty]]):