How to GET all keys and values of Object in JavaScript
Object.keys(), Object.values(), and Object.entries() are three static methods that extract an object's own enumerable properties as arrays, each returning a different slice of that data.
Theory
TL;DR
- Object is like a labeled filing cabinet: keys are the labels, values are the contents, entries give you both together
- All three methods return arrays of own enumerable properties only, no prototype chain, no Symbol keys
Object.keys()for names,Object.values()for data,Object.entries()for pairs- Need to loop with destructuring?
entries()+for...of. Need values only to map over?values() - Insertion order is preserved (ES2015+)
Quick example
const user = { name: "Alice", age: 25, role: "admin" };
Object.keys(user); // ["name", "age", "role"]
Object.values(user); // ["Alice", 25, "admin"]
Object.entries(user); // [["name", "Alice"], ["age", 25], ["role", "admin"]]
// Iterate with destructuring
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`); // "name: Alice", "age: 25", "role: admin"
}All three snapshot the object's state at the moment of the call.
Key difference
These methods only see own enumerable properties. That means no inherited props from the prototype chain, and no Symbol keys. for...in walks the full prototype chain, which is why you historically needed hasOwnProperty() with it. These three methods skip that problem entirely.
When to use
Object.keys()- check what properties exist or build a names list:Object.keys(config).includes("timeout")Object.values()- transform or aggregate values:Object.values(prices).reduce((sum, p) => sum + p, 0)Object.entries()- need key and value together, or converting to aMap:new Map(Object.entries(obj))for...in- only for legacy code that explicitly needs prototype-inherited properties
Comparison table
| Method | Returns | Own props only? | Order preserved? |
|---|---|---|---|
Object.keys() | string[] | Yes | Yes (ES2015+) |
Object.values() | any[] | Yes | Yes (ES2015+) |
Object.entries() | [string, any][] | Yes | Yes (ES2015+) |
for...in | Iterates keys | No (includes proto) | Not guaranteed |
| When to use | keys for names, values for data, entries for pairs or Map conversion, for...in only when you need inherited props |
How it works
V8 enumerates the object's own string-keyed properties via hidden class descriptors and builds a new array in insertion order (stable since ES2015). Symbol keys are skipped entirely. Getters run during Object.values(), so the array reflects whatever the getter returns at that moment. Need Symbol keys too? Use Reflect.ownKeys(obj).
Common mistakes
Mistake: expecting Symbol keys in the output
const obj = { a: 1, [Symbol("id")]: 42 };
Object.keys(obj); // ["a"] - Symbol is gone
// Fix:
Reflect.ownKeys(obj); // ["a", Symbol(id)]Symbols are invisible to all three methods. This trips people up often.
Mistake: using for...in on plain objects and getting inherited properties
function Base() {}
Base.prototype.inherited = "oops";
const obj = new Base();
obj.own = "mine";
for (const key in obj) {
console.log(key); // "own", "inherited" - prototype props leak in
}
// These three methods avoid this:
Object.keys(obj); // ["own"]Mistake: mutating the object during iteration
const obj = { a: 1, b: 2 };
for (const [k, v] of Object.entries(obj)) {
obj[`copy_${k}`] = v; // adding props while looping
}
// The loop only sees "a" and "b" - entries() snapshotted at call time
// The object ends up with extra keys, which can cause bugs later
// Fix: clone first
for (const [k, v] of Object.entries({ ...obj })) {
obj[`copy_${k}`] = v;
}Real-world usage
- React -
Object.entries(props)to render dynamic<option>elements in a select - Redux -
Object.keys(state.entities)to extract IDs for selectors - Express -
Object.values(req.headers)to log all header values - Node.js -
Object.entries(process.env)to safely iterate environment variables - Lodash - uses
entries()internally for.toPairs()and.fromPairs()
Follow-up questions
Q: What does Object.keys({}) return?
A: An empty array []. No properties means no keys.
Q: What is the difference between Object.keys() and for...in?
A: Object.keys() returns only own enumerable string keys, in insertion order. for...in walks the entire prototype chain and order is not guaranteed. In modern code, prefer Object.keys().
Q: Does Object.values() execute getter functions?
A: Yes. If a property is defined with a getter, Object.values() calls it and puts the result in the array.
Q: How do you get all keys including Symbols?
A: Use Reflect.ownKeys(obj). It returns own string keys plus own Symbol keys in one array.
Q: You add a property to an object after calling Object.entries(). Does the iteration see it?
A: No. Object.entries() creates a snapshot at the time of the call. Properties added after that are not included.
Examples
Getting keys, values, and entries from a config object
const config = {
host: "localhost",
port: 3000,
debug: true
};
// Check if a key exists (own property only)
Object.keys(config).includes("port"); // true
// Join all values into a string
Object.values(config).join(", "); // "localhost, 3000, true"
// Build a query string from entries
const query = Object.entries(config)
.map(([key, value]) => `${key}=${value}`)
.join("&");
// "host=localhost&port=3000&debug=true"Object.keys() handles existence checks without touching values. Object.entries() is the right pick when you need both sides at once.
Converting an API response to a Map
// API returns a flat object with dynamic keys
const permissions = {
read: true,
write: false,
delete: true
};
// Convert to Map for fast key lookup
const permMap = new Map(Object.entries(permissions));
permMap.get("write"); // false
permMap.has("admin"); // false
// Filter only active permissions
const active = Object.entries(permissions)
.filter(([, value]) => value === true)
.map(([key]) => key);
// ["read", "delete"]I reach for this pattern any time an API returns a settings or permissions object with keys I don't know upfront. A Map handles dynamic lookups more cleanly than repeated in checks.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.