Iterating Over JavaScript Object Entries and their Performance - 5 Techniques

134,314 reads

This post includes 5 different ways for iterating over JavaScript Object entries and a performance comparison of those techniques.

reactions

Technique 1 : Object.entries

Object.entries() returns a list of key, value pairs. This list includes only enumerable properties and doesn’t include properties from prototype chain.

reactions

Enumerable Properties?

Properties created via simple assignment or via a property initializer

reactions

let obj = { key1 : "value1" , key2 : "value2" , key3 : "value3" } Object .entries(obj).forEach( entry => { let key = entry[ 0 ]; let value = entry[ 1 ]; //use key and value here });

Github gist

reactions

Technique 2 : Object.keys

Object.keys() returns an array of object keys. However, this function returns only enumerable properties.

reactions

let obj = { key1 : "value1" , key2 : "value2" , key3 : "value3" } Object .keys(obj).forEach( key => { let value = obj[key]; //use key and value here });

Github gist

reactions

Technique 3 : Object.values

Object.values() returns an array of object property values. This function returns values of enumerable properties only.

reactions

let obj = { key1 : "value1" , key2 : "value2" , key3 : "value3" } Object .values(obj).forEach( value => { //use value here });

Github gist

reactions

Technique 4 : for…in loop

for…in loop can be used to iterate over enumerable properties of JavaScript objects. This loop includes inherited properties from prototype chain.

reactions

let obj = { key1 : "value1" , key2 : "value2" , key3 : "value3" } for ( const key in obj) { let value = obj[key]; //optional check for properties from prototype chain if (obj.hasOwnProperty(key)) { //no a property from prototype chain } else { //property from protytpe chain } }

Github gist

reactions

Technique 5 : Object.getOwnPropertyNames

Object.getOwnPropertyNames returns all the properties of an object including non enumerable properties. The result set will also include properties inherited from prototype chain.

reactions

let obj = { key1 : "value1" , key2 : "value2" , key3 : "value3" } Object .getOwnPropertyNames(obj).forEach( key => { let value = obj[key]; //use key and value here });

Github gist

reactions

Performance Comparison

In order to compare the performance of each of above techniques, following script was executed for 1000 objects having 1 million properties in each.

reactions

const { PerformanceObserver, performance } = require ( 'perf_hooks' ); let objectSize = 1000000 ; let iterations = 10 ; console .log( "Starting performance test with %d object size and %d iterations" , objectSize, iterations); let values = { ENTRIES : 0 , KEYS : 0 , VALUES : 0 , FORIN : 0 , GETOWP : 0 } const obs = new PerformanceObserver( ( items ) => { let entry = items.getEntries()[ 0 ]; console .log(entry.name, entry.duration); values[entry.name] += entry.duration; performance.clearMarks(); }); obs.observe({ entryTypes : [ 'measure' ] }); function generateObject ( ) { let obj = {}; for ( let i = 0 ; i < objectSize; i++) { obj[ 'key' + i] = 'val' + i; } return obj; } for ( let i = 0 ; i < iterations; i++) { let obj = generateObject(); //Object.entries performance.mark( 'A' ); Object .entries(obj).forEach( entry => { let key = entry[ 0 ]; let value = entry[ 1 ]; }); performance.mark( 'B' ); performance.measure( 'ENTRIES' , 'A' , 'B' ); //Object.Keys performance.mark( 'A' ); Object .keys(obj).forEach( key => { let value = obj[key]; }); performance.mark( 'B' ); performance.measure( 'KEYS' , 'A' , 'B' ); //Object.Values performance.mark( 'A' ); Object .values(obj).forEach( value => { }); performance.mark( 'B' ); performance.measure( 'VALUES' , 'A' , 'B' ); //For In performance.mark( 'A' ); for ( const key in obj) { let value = obj[key]; } performance.mark( 'B' ); performance.measure( 'FORIN' , 'A' , 'B' ); //Object.getOwnPropertyNames performance.mark( 'A' ); Object .getOwnPropertyNames(obj).forEach( key => { let value = obj[key]; }); performance.mark( 'B' ); performance.measure( 'GETOWP' , 'A' , 'B' ); } console .log( Object .entries(values).sort( ( a, b ) => { return a[ 1 ] - b[ 1 ]; }));

Github gist

reactions

Results

Performance test results

reactions

Chart below gives a better comparison overview of the techniques.

reactions

Performance comparison of JavaScript Object iteration techniques

reactions

Based on above results, the winner or the fastest technique to iterate over JavaScript Object entries is for…in.

reactions

Call To Action

Clap. Appreciate and let others find this article.

reactions

Comment. Share your views on this article.

reactions

Follow me. Chathura Widanage to receive updates on articles like this.

reactions

Keep in touch. LinkedIn, Twitter

reactions

Originally published at gists.cwidanage.com.

reactions

Tags