Lodash _.keys() method
What you’ll learn
- How
_.keys(object)returns an array of own enumerable string-keyed property names. - What gets excluded: inherited, non-enumerable, and symbol-keyed properties.
- How arrays, strings,
null, andundefinedbehave. - When to use _.keysIn(),
Object.keys(), orReflect.ownKeys()instead.
Prerequisites
You should know the difference between own and inherited properties, and between enumerable and non-enumerable properties.
- Own only: prototype properties are ignored. Use
_.keysInif you need inherited keys. - Enumerable only: properties defined with
enumerable: falsedo not appear. - String keys only: symbol keys require
Object.getOwnPropertySymbolsorReflect.ownKeys.
Overview
_.keys is Lodash’s object-name enumerator for the common case: own, enumerable, string-keyed properties. It is close to Object.keys, but it handles null and undefined more gently by returning an empty array. For objects with prototypes, symbols, or non-enumerable metadata, choose the narrower or broader native API intentionally.
Own enumerable names
The same mental model as forOwn and most DTO-building helpers.
Null-safe
_.keys(null) and _.keys(undefined) return [] instead of throwing.
Not a deep helper
It returns only first-level property names. It does not walk nested objects.
Syntax
_.keys(object) - object: value to inspect. Objects, arrays, strings, and array-like values are supported.
- Returns: an array of own enumerable string-keyed property names.
Get own enumerable keys
For plain objects, _.keys returns the same useful surface you normally want to iterate or validate.
import keys from "lodash/keys";
const user = {
name: "John",
age: 30,
email: "john@example.com"
};
keys(user);
// -> ["name", "age", "email"]
keys(user).forEach((key) => {
console.log(key + ": " + user[key]);
});
// name: John
// age: 30
// email: john@example.com Arrays, strings, null and undefined
Array indexes and string character positions are keys too. Lodash also avoids the Object.keys(null) throw by returning an empty array.
import keys from "lodash/keys";
keys(["a", "b", "c"]);
// -> ["0", "1", "2"]
const sparse = [];
sparse[2] = "two";
keys(sparse);
// -> ["0", "1", "2"]
// Lodash iterates 0..length-1 for array-likes, so holes are reported.
// Object.keys(sparse) returns only ["2"] for the same array.
keys("hi");
// -> ["0", "1"]
keys(null);
// -> []
keys(undefined);
// -> [] Inherited, non-enumerable and symbol keys
_.keys is deliberately narrow. If a property is inherited, non-enumerable, or symbol-keyed, it will not appear.
import keys from "lodash/keys";
import keysIn from "lodash/keysIn";
const hidden = Symbol("hidden");
const proto = { inherited: true };
const obj = Object.create(proto);
obj.visible = 1;
obj[hidden] = 2;
Object.defineProperty(obj, "secret", {
value: 3,
enumerable: false
});
keys(obj);
// -> ["visible"]
keysIn(obj);
// -> ["visible", "inherited"]
Object.getOwnPropertyNames(obj);
// -> ["visible", "secret"]
Reflect.ownKeys(obj);
// -> ["visible", "secret", Symbol(hidden)] 📋 _.keys vs related APIs
| Topic | _.keys | _.keysIn | Object.keys | Reflect.ownKeys |
|---|---|---|---|---|
| Own string keys | Yes | Yes | Yes | Yes |
| Inherited string keys | No | Yes | No | No |
| Non-enumerable keys | No | No | No | Yes |
| Symbol keys | No | No | No | Yes |
null / undefined | [] | [] | Throws | Throws |
Use _.keys for DTO-style own enumerable names, _.keysIn when inherited enumerable keys are part of the public shape, and Reflect.ownKeys when symbols or non-enumerable metadata matter.
Pitfalls to avoid
Prototype keys are excluded
This is usually what you want. If your object intentionally exposes enumerable prototype properties, use _.keysIn.
Symbols are not returned
_.keys returns names, not symbols. Use Reflect.ownKeys or Object.getOwnPropertySymbols for symbol-aware code.
Sort when order matters
Property order is predictable by spec, but business logic should not depend on incoming object order. Sort the returned array if order is meaningful.
Strings produce character index keys
The old reference suggested invalid values return empty arrays, but _.keys("hi") returns ["0", "1"].
Sparse arrays differ from Object.keys
Lodash treats array-likes as a 0..length-1 index range, so holes are returned. Object.keys reports only assigned indexes. Pick the helper that matches your data model.
❓ FAQ
Summary
- Purpose: return an array of own enumerable string-keyed property names.
- Remember: inherited, non-enumerable, and symbol-keyed properties are excluded.
- Next: Lodash _.keysIn(), _.values(), or the official Lodash docs for _.keys.
_.keys returns only own enumerable string-keyed property names. It ignores inherited properties, non-enumerable properties, and symbol-keyed properties.
5 people found this page helpful
