How Lodash _.valuesIn Works with Prototype Chains

The Lodash method _.valuesIn creates an array of values corresponding to all enumerable string-keyed properties of an object, including both its own properties and those inherited through its prototype chain. While standard methods like Object.values() and Lodash's own _.values() restrict their output strictly to direct, "own" properties, _.valuesIn traverses the prototype hierarchy to collect every accessible enumerable value. This article explains the internal mechanics, inheritance rules, and code patterns behind how _.valuesIn navigates prototype chains.

The Underlying Mechanism of _.valuesIn

At its core, _.valuesIn works by identifying all enumerable keys across the entire prototype tree and mapping those keys to their respective values on the target object.

In native JavaScript, the for...in statement natively traverses both an object's own enumerable properties and the enumerable properties of its prototype chain up to Object.prototype. Internally, Lodash achieves the behavior of _.valuesIn through a two-step process:

  1. Extracting Keys via keysIn: Lodash first calls an internal utility similar to _.keysIn(object). This step inspects the object and iteratively climbs its prototype hierarchy (using mechanisms analogous to Object.getPrototypeOf), collecting all enumerable string property names.
  2. Value Mapping: Once the collection of keys is generated, Lodash iterates over them and reads the value associated with each key directly from the target object: object[key].

Because property access via bracket notation (object[key]) automatically resolves up the prototype chain if the property does not exist directly on the instance, inherited values are seamlessly returned.

Code Example: Own vs. Inherited Values

To see the difference in execution, consider a parent-child relationship created via prototypes:

const _ = require('lodash');

// Define a prototype parent object
const parent = {
  inheritedProp: 'inherited value'
};

// Create a child object inheriting from parent
const child = Object.create(parent);
child.ownProp = 'own value';

// Lodash _.values only checks own properties
console.log(_.values(child)); 
// Output: ['own value']

// Lodash _.valuesIn includes the prototype chain
console.log(_.valuesIn(child)); 
// Output: ['own value', 'inherited value']

Property Shadowing

If an object defines a property that shares the exact same key name as a property on its prototype, the own property "shadows" the prototype property.

When _.valuesIn encounters shadowed properties, it does not output duplicate keys or overridden values. Because standard JavaScript key resolution halts at the first matching key found in the chain, _.valuesIn only retrieves the most derived value (the one highest up in the priority order).

const vehicle = { wheels: 4 };
const bicycle = Object.create(vehicle);
bicycle.wheels = 2; // Shadows 'wheels' from prototype

console.log(_.valuesIn(bicycle));
// Output: [2] (The inherited value 4 is ignored due to shadowing)

The Role of Property Enumerability

_.valuesIn only extracts values for properties flagged as enumerable.

Properties added using standard assignment (obj.prop = value) or object literals are enumerable by default. However, properties defined using Object.defineProperty with enumerable: false, or built-in prototype methods such as toString, valueOf, and hasOwnProperty on Object.prototype, have their enumerable descriptor set to false. As a result, _.valuesIn automatically ignores native utility methods on the root object prototype, ensuring the returned array only contains user-defined or explicitly enumerable inherited values.