Object.keys, Object.values, Object.entries in Modern JavaScript Iterating over and introspecting objects has evolved significantly from the error-prone for...in loops of early JavaScript. Modern standards provide static methods on Object that return standard arrays of an object's enumerable own properties, integrating seamlessly with array methods like .map(), .filter(), and .forEach().
Object.keys(obj) returns an array of a given object's own enumerable property names (keys) :
1 const config = {
2 theme : 'dark' ,
3 version : '2.4.0' ,
4 autoSave : true
5 } ;
6
7 const keys = Object . keys ( config ) ;
8 console . log ( keys ) ; // ['theme', 'version', 'autoSave']
9
10 // Checking if an object is empty
11 const isEmpty = Object . keys ( config ) . length === 0 ;
Object.values(obj) returns an array of a given object's own enumerable property values :
1 const monthlySales = {
2 january : 12000 ,
3 february : 15500 ,
4 march : 18200
5 } ;
6
7 const revenues = Object . values ( monthlySales ) ;
8 console . log ( revenues ) ; // [12000, 15500, 18200]
9
10 const quarterTotal = revenues . reduce ( ( sum , val ) => sum + val , 0 ) ;
11 console . log ( 'Q1 Revenue:' , quarterTotal ) ; // 45700
Object.entries(obj) returns an array of a given object's own enumerable string-keyed [key, value] pairs :
1 const userRoles = {
2 alice : 'Admin' ,
3 bob : 'Editor' ,
4 charlie : 'Viewer'
5 } ;
6
7 const entries = Object . entries ( userRoles ) ;
8 console . log ( entries ) ;
9 // [
10 // ['alice', 'Admin'],
11 // ['bob', 'Editor'],
12 // ['charlie', 'Viewer']
13 // ]
Destructuring in Loops with for...of 1 for ( const [ user , role ] of Object . entries ( userRoles ) ) {
2 console . log ( ` User ${ user } has role permission: ${ role } ` ) ;
3 }
Object.fromEntries() performs the inverse of Object.entries(), transforming a list of key-value pairs back into an object. This enables filtering and transforming objects using standard array methods:
1 Original Object
2 │
3 ▼
4 Object.entries() ───► [ [k1, v1], [k2, v2] ]
5 │
6 .filter() / .map()
7 │
8 ▲ ▼
9 Object.fromEntries() ◄── [ [k1, newVal1] ]
10 │
11 Transformed Object
1 const inventory = {
2 apples : 15 ,
3 oranges : 0 ,
4 bananas : 28 ,
5 peaches : 0
6 } ;
7
8 // Filter out out-of-stock items (value > 0)
9 const inStockInventory = Object . fromEntries (
10 Object . entries ( inventory ) . filter ( ( [ _ , count ] ) => count > 0 )
11 ) ;
12
13 console . log ( inStockInventory ) ;
14 // { apples: 15, bananas: 28 }
1 // AVOID: for...in iterates over inherited prototype properties!
2 for ( const key in obj ) {
3 if ( Object . hasOwn ( obj , key ) ) { // Required boilerplate to prevent prototype leakage
4 console . log ( key ) ;
5 }
6 }
7
8 // PREFERRED: Object.keys() only returns own enumerable properties
9 Object . keys ( obj ) . forEach ( key => console . log ( key ) ) ;
Interactive Quiz • Knowledge Check
Practice Quiz What does Object.keys({ a: 1, b: 2 }) return?
A { 'a': 1, 'b': 2 }
B ['a', 'b']
C [1, 2]
D [['a', 1], ['b', 2]]
How do you verify if a plain JavaScript object is completely empty ({})?
A obj === {}
B Object.keys(obj).length === 0
C obj.isEmpty()
D obj.length === 0
Which method is the inverse of Object.entries(), converting [ [key, val], ... ] pairs back into an object?
A Object.toObject()
B Object.fromEntries()
C Object.reconstruct()
D Object.parse()
What does Object.entries({ score: 100 }) return?
A ['score', 100]
B [['score', 100]]
C { key: 'score', value: 100 }
D 'score: 100'
Why is Object.values() preferred over a manual for...in loop with obj[key]?
A It returns a standard Array directly, allowing method chaining (.map, .reduce) while ignoring prototype properties
B It runs in a GPU thread
C for...in does not work in modern browsers
D Object.values() sorts the values numerically automatically