Object.keys()
Object.keys() returns an array of an object's own enumerable string keys — the standard way to count properties or iterate over an object by turning it into an array first.
Definition
Object.keys() returns an array containing the names of an object's own enumerable string-keyed properties. It is the most common first step in working with an object as data: once you have the keys as an array, you can count them, iterate them, sort them, or map over them like any other array.
"Own" means it ignores properties inherited from the prototype chain, and "enumerable" means it skips the handful of properties explicitly hidden from enumeration. For the plain objects you build with {}, that's simply every key you put in — which is exactly what you want.
Because the result is an ordinary array, everything you know about arrays applies at once: .length counts the properties, .map() transforms the keys, .filter() selects some, .sort() orders them. That is the whole appeal of Object.keys() — it converts the things objects are awkward at (counting, iterating, transforming) into the things arrays are best at, in a single call, without you writing a loop by hand.
Syntax
Object.keys(obj)
// obj: the object whose own enumerable keys you want
// returns: a new array of strings
Parameters
| Parameter | Required | Description |
|---|---|---|
obj | Yes | The object to read keys from. A non-object argument is coerced to an object first (e.g. a string yields its index keys). |
Object.keys() is a static method — you call it as Object.keys(obj), not obj.keys(). Its siblings Object.values(obj) and Object.entries(obj) follow the same shape, returning the values and the [key, value] pairs respectively.
Return value
A new array of the object's own enumerable keys, as strings. An object with no such properties returns an empty array. The original object is not modified.
- Integer-like keys come first, in ascending numeric order; all other string keys follow in insertion order.
- Symbol keys are never included (use
Object.getOwnPropertySymbolsfor those). - Inherited (prototype) properties are excluded.
Examples
Count and list the keys
Iterate an object via its keys
const scores = { math: 90, art: 78 };
Object.keys(scores).forEach((key) => {
console.log(`${key}: ${scores[key]}`);
});
// math: 90
// art: 78
Check whether an object is empty
const isEmpty = (obj) => Object.keys(obj).length === 0;
console.log(isEmpty({})); // true
console.log(isEmpty({ a: 1 })); // false
Transform keys with map
const prices = { pen: 3, book: 12 };
const labels = Object.keys(prices).map((k) => k.toUpperCase());
console.log(labels); // ['PEN', 'BOOK']
Sort the keys alphabetically
const obj = { banana: 1, apple: 2, cherry: 3 };
const sortedKeys = Object.keys(obj).sort();
console.log(sortedKeys); // ['apple', 'banana', 'cherry']
Browser & runtime support
Object.keys() vs for...in
Both visit an object's keys, but Object.keys() returns only the object's own enumerable keys as an array, while a for...in loop also walks inherited enumerable keys from the prototype chain. That inherited behavior is a classic source of bugs, which is why Object.keys() (or Object.entries()) is the safer, more predictable default — you get a clean array of exactly the object's own properties, and array methods to process it.
A related method, Object.getOwnPropertyNames(), returns non-enumerable own keys too, which Object.keys() deliberately skips. In everyday code you almost always want Object.keys(): the properties you set on a plain object literal are all enumerable, so it lines up with what JSON.stringify() serialises and with the own keys for...in would see. Reach for getOwnPropertyNames only when you are deliberately inspecting hidden, non-enumerable properties.
One performance note: each call allocates a fresh array, so avoid calling Object.keys() repeatedly on the same object inside a hot loop — capture it once in a variable and reuse it. For the object sizes you meet in ordinary application code the cost is negligible and clarity wins, but it is worth knowing when a loop runs millions of times.
Availability
Object.keys() has been standard since ECMAScript 5 (2009) and works in every modern browser and every maintained version of Node.js. The guaranteed key order (integers first, then insertion order) was formalised in ES2015 and is safe to rely on today.
Frequently asked questions
What order does Object.keys() return keys in?
Does Object.keys() include inherited properties?
How do I count the properties of an object?
Object.keys(obj).length, which gives the number of own enumerable properties.Why is it Object.keys(obj) and not obj.keys()?
keys method to every object you create.