Lodash _.keysIn() method

Beginner
⏱️ 6 min read
📚 Updated: May 2026
🎯 3 Code examples
🚀 3 Try-it labs
Lodash

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, and Reflect.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

javascript
_.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.
1

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.

javascript
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
Try it Yourself
2

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.

javascript
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"]
Try it Yourself
3

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.

javascript
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); // -> []
Try it Yourself

📋 _.keysIn vs related APIs

Topic_.keysIn_.keysfor...inReflect.ownKeys
Own string keysYesYesYesYes
Inherited string keysYesNoYesNo
Non-enumerable keysNoNoNoYes
Symbol keysNoNoNoYes
Returns arrayYesYesNo (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

Class

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.

Pollution

Polluted Object.prototype leaks in

Anything assigned enumerably to Object.prototype shows up for every object you inspect. Validate untrusted code paths.

Symbols

Symbols are excluded

String keys only. Walk the prototype chain manually with Reflect.ownKeys when symbols are required.

Order

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

An array of own and inherited enumerable string-keyed property names. It is the prototype-aware sibling of _.keys.
_.keys only includes own enumerable string keys. _.keysIn additionally walks the prototype chain and includes inherited enumerable string keys.
Usually no. ES class methods live on the prototype, but they are defined as non-enumerable, and _.keysIn only reports enumerable properties. Older constructor.prototype.method = fn assignments are enumerable, so those do appear.
for...in also walks own and inherited enumerable string keys, but it does so as a statement rather than returning an array. _.keysIn gives you the array up front for further iteration or filtering.
No. It returns string-keyed property names only. Use Reflect.ownKeys with manual prototype walking if symbols matter.
Yes. _.keysIn(null) and _.keysIn(undefined) both return an empty array instead of throwing.

Summary

Did you know?

_.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.

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful