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:
- 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 toObject.getPrototypeOf), collecting all enumerable string property names. - 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.