Lodash _.keysIn() method
What you’ll learn
- How
_.keysIn(object)returns own and inherited enumerable string-keyed property names. - Why ES class methods typically don’t appear (non-enumerable on the prototype).
- Why older constructor/prototype assignments do appear (enumerable by default).
- How to choose between
_.keysIn, _.keys(),for...in, andReflect.ownKeys.
Prerequisites
You should know what own vs. inherited properties are, and how enumerable property descriptors work.
- Walks the chain: inherited enumerable string keys are part of the result.
- Enumerable only: non-enumerable properties—including ES class methods—don’t appear.
- Strings, no symbols: symbol-keyed properties are excluded.
Overview
_.keysIn is essentially a for...in in array form. It collects every enumerable string-keyed property along the prototype chain into a single array—useful for mixin-style objects and old-style constructor APIs where the inherited surface is intentional.
Prototype-aware
Inherited enumerable string keys are reported alongside own keys.
Null-safe
_.keysIn(null) and _.keysIn(undefined) return [], not a thrown error.
Skips non-enumerable
ES class methods don’t appear because the prototype defines them as non-enumerable.
Syntax
_.keysIn(object) - object: value to inspect. Objects, arrays, strings, and array-like values are supported.
- Returns: an array of own and inherited enumerable string-keyed property names.
Inherited prototype properties
Constructor/prototype assignments are enumerable by default, so they show up alongside own properties—exactly the case where _.keysIn shines over _.keys.
import keysIn from "lodash/keysIn";
import keys from "lodash/keys";
function Vehicle(make, model) {
this.make = make;
this.model = model;
}
Vehicle.prototype.start = function () {
return "Starting the vehicle";
};
const car = new Vehicle("Toyota", "Camry");
keys(car);
// -> ["make", "model"]
// own only
keysIn(car);
// -> ["make", "model", "start"]
// "start" is inherited and enumerable ES class methods are non-enumerable
Modern class syntax defines prototype methods as non-enumerable. That means _.keysIn will not list them—use Reflect.ownKeys or manual descriptor inspection when you need to discover class methods.
import keysIn from "lodash/keysIn";
class User {
constructor(name) {
this.name = name;
}
greet() {
return "Hi " + this.name;
}
}
const u = new User("Ada");
keysIn(u);
// -> ["name"]
// greet is on the prototype but non-enumerable.
// Manual lookup if you need class methods:
const protoNames = Object.getOwnPropertyNames(Object.getPrototypeOf(u))
.filter((name) => name !== "constructor");
// -> ["greet"] Mixins & Object.create prototypes
_.keysIn mirrors for...in, so it’s a clean way to enumerate mixin or Object.create compositions where inherited keys are intentionally part of the public shape.
import keysIn from "lodash/keysIn";
const animal = { legs: 4, tail: true };
const dog = Object.create(animal);
dog.name = "Buddy";
keysIn(dog);
// -> ["name", "legs", "tail"]
keysIn({ a: 1, b: 2 });
// -> ["a", "b"] (no prototype to walk, same as _.keys)
keysIn(null); // -> []
keysIn(undefined); // -> [] 📋 _.keysIn vs related APIs
| Topic | _.keysIn | _.keys | for...in | Reflect.ownKeys |
|---|---|---|---|---|
| Own string keys | Yes | Yes | Yes | Yes |
| Inherited string keys | Yes | No | Yes | No |
| Non-enumerable keys | No | No | No | Yes |
| Symbol keys | No | No | No | Yes |
| Returns array | Yes | Yes | No (statement) | Yes |
Pick _.keysIn when inherited enumerable keys are part of the API. Pick _.keys for own-only DTO work. Reach for Reflect.ownKeys when symbols or non-enumerable metadata matter.
Pitfalls to avoid
ES class methods are hidden
class { method() {} } defines method as non-enumerable, so it never appears in _.keysIn. Use Object.getOwnPropertyNames on the prototype if you need them.
Polluted Object.prototype leaks in
Anything assigned enumerably to Object.prototype shows up for every object you inspect. Validate untrusted code paths.
Symbols are excluded
String keys only. Walk the prototype chain manually with Reflect.ownKeys when symbols are required.
Order spans the chain
Own enumerable keys come first, followed by inherited keys walking up the prototype chain. Sort the array if you need a stable user-facing order.
❓ FAQ
Summary
- Purpose: return own and inherited enumerable string-keyed property names.
- Remember: ES class methods are non-enumerable and won’t show up.
- Next: Lodash _.mapKeys(), _.keys(), or the official Lodash docs for _.keysIn.
_.keysIn walks the prototype chain—but it still only sees enumerable properties. ES class methods are non-enumerable on the prototype, so they will not appear. Older constructor/prototype assignments are enumerable by default, which is why they do.
5 people found this page helpful
