Lesson 42: Mastering JavaScript Object.keys, Object.values, and Object.entries with challenges!

What Are These Methods?
They allow you to extract keys, values, or key-value pairs from plain JavaScript objects (not arrays, not maps):
const user = { name: "Alice", age: 25 };
Object.keys(user); // ["name", "age"]
Object.values(user); // ["Alice", 25]
Object.entries(user);// [["name", "Alice"], ["age", 25]]
Key Characteristics:
Method | Return Type | Iterates Over | Notes |
Object.keys(obj) | string[] | enumerable keys | Returns only own (non-inherited) enumerable keys |
Object.values(obj) | any[] | enumerable values | Same as above |
Object.entries(obj) | [string, any][] | key-value pairs | Great for transformation pipelines |
Visualization:
const obj = { a: 1, b: 2 };
Object.entries(obj) ➝
[
["a", 1],
["b", 2]
]
🔹 2. Fill Any Gaps
🔸 Symbols Are Ignored
const sym = Symbol("hidden");
const obj = { a: 1, [sym]: 42 };
Object.keys(obj); // ["a"]
Object.getOwnPropertySymbols(obj); // [Symbol(hidden)]
Reflect.ownKeys(obj); // ["a", Symbol(hidden)]
🔸 Order of Keys
Numeric-like keys come first, sorted as numbers.
Then string keys in insertion order.
Then symbol keys (not included in
Object.keys/values/entries
).
const obj = { 10: 'a', 2: 'b', x: 'c' };
console.log(Object.keys(obj)); // ["2", "10", "x"]
🔸 Only "own" and enumerable keys
const proto = { inherited: 1 };
const obj = Object.create(proto);
obj.own = 2;
Object.keys(obj); // ["own"]
🔸 Not directly on the object
const obj = { a: 1 };
// obj.keys() ❌ → TypeError
Object.keys(obj); // ✅
🔹 3. Challenge Me Deeply
🟢 Basic
Create an object and use
Object.keys
,Object.values
, andObject.entries
to log its structure.Write a function
sumValues(obj)
that returns the sum of all numeric values in an object.Use
for..of
andObject.entries
to print key-value pairs with a dash separator (key - value
).
🟡 Intermediate
Write a function that filters out all key-value pairs where the value is falsy (e.g.,
0
,null
,undefined
,false
,""
).Implement an
invertObject(obj)
function that swaps keys and values.Write a
deepLog(obj)
that logs each key and its value's type usingObject.entries
.Given a prices object, return a new object with a 10% discount applied to each price.
🔴 Advanced
Write a function that deeply clones an object only using
Object.entries
(nostructuredClone
orJSON.parse
).Create a
serialize(obj)
function that flattens nested objects into a key path representation:// Input: { a: 1, b: { c: 2 } } // Output: { "a": 1, "b.c": 2 }
Write a function
renameKeys(obj, renameMap)
that takes an object and a mapping of old keys to new ones and returns a new object with renamed keys.
🎯 Brain-Twister
- Why doesn’t the following work as expected?
const obj = { 1: "a", 2: "b" };
console.log(Object.keys(obj)); // ?
console.log(Object.entries(obj)[0][0] === 1); // true or false?
🔹 4. Interview-Ready Questions
🔍 Conceptual
What’s the difference between
for...in
andObject.keys()
?Why doesn’t
Object.keys
return symbol keys?How is the key order determined in
Object.keys()
?
⚠️ Debugging / Tricky
You're using
Object.entries(obj)
and modifying the array it returns. Will that affect the original object?Someone wrote
obj.keys()
. Why doesn’t it work? How would you fix it?You use
Object.keys(obj).map(...)
on a prototype-based object and it returns fewer keys than expected. Why?
💼 Real-World Interview Simulation
You’re given an object of configuration settings from a legacy API. Write code that:
Removes any null or undefined values
Converts all keys to camelCase (assume helper provided)
Returns a new cleaned object
✅ Best Practices
✅ Use
Object.entries().map().fromEntries()
for object transformations.✅ Avoid mutating objects during iteration.
✅ Prefer
Reflect.ownKeys()
when symbols matter.
❌ Red Flags
❌ Using
for...in
withouthasOwnProperty
guard.❌ Relying on key order without understanding it.
❌ Using
obj.keys()
instead ofObject.keys(obj)
.
🔹 5. Real-World Usage
🔧 In Frameworks & Libraries
React: Dynamic prop mapping or form handling
Express: Cleaning or transforming
req.query
orreq.body
Lodash: Utilities like
_.mapValues
,_.invert
wrap around similar patternsMongoDB Aggregation: Often transformed to/from key-value pairs for computation
🧪 Testing
Use Object.entries(obj).every(([key, val]) => typeof val === 'string')
to assert value types.
🔹 6. Remember Like a Pro
🧠 Mnemonic:
KVE = Keys
, Values
, Entries
— Think:
K = list of property Keys
V = list of property Values
E = Everything (keys and values)
🔁 Mind Map:
+----------------+
| Plain Objects |
+----------------+
|
+------------+-------------+
| | |
Object.keys Object.values Object.entries
(keys) (values) (pairs)
🧾 Cheatsheet:
Object.keys(obj) // [key1, key2, ...]
Object.values(obj) // [value1, value2, ...]
Object.entries(obj) // [[key1, value1], [key2, value2], ...]
Object.fromEntries([[key, val]]) // → Recreate object
Reflect.ownKeys(obj) // Includes Symbol keys
Object.getOwnPropertySymbols(obj) // Only symbols
🔹 7. Apply It in a Fun Way
🛠 Mini Project: “Budget Transformer”
Goal: Input a nested object of categories and prices, output a cleaned and flattened object with transformed values.
Steps:
Take a nested object like:
{ food: { banana: 1, meat: 5 }, drinks: { water: 1, soda: 2 } }
Flatten it to:
{ "food.banana": 1, "food.meat": 5, "drinks.water": 1, "drinks.soda": 2 }
Multiply each price by 1.15 for tax
Use
Object.entries
,map
, andObject.fromEntries
to achieve this.
Bonus Extension:
Add ability to exclude zero or negative values.
Support deeper nesting with recursion.
➕ Bonus Insights
🔍 Common Mistakes:
Assuming order of
Object.keys()
is always insertion order (not true with numeric keys).Using
Object.keys()
to iterate over arrays — preferarray.forEach
.
⚡ Performance Tips:
Object.keys()
is faster thanfor...in
due to no prototype chain traversal.Avoid repeatedly calling
Object.entries()
in a loop.
📦 Used Heavily In:
JSON manipulation
Config builders
React props mapping
Form validation logic
Subscribe to my newsletter
Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
