Object.entries
Returns all enumerable
key-value pairs of the object, and will not track the key on the prototype chain
let obj = { key1: 'value1', key2: 'value2', key3: & # 39; value3 & # 39;, } Object.entries(obj).forEach(entry => { let key = entry[0] let value = entry[1] // entry will be like ["key1", "value1"] })
Object.keys
Return all enumerable keys of the object
let obj = { key1: 'value1', key2: 'value2', key3: & # 39; value3 & # 39;, } Object.keys(obj).forEach(key => { let value = obj[key] })
Object.values
Return all enumerable values of the object
let obj = { key1: 'value1', key2: 'value2', key3: & # 39; value3 & # 39;, } Object.values(obj).forEach(value => { // only use value })
for…in loop
Iterative enumerable properties will be found along the prototype chain
let obj = { key1: 'value1', key2: 'value2', key3: & # 39; value3 & # 39;, } for (const key in obj) { let value = obj[key] if (obj. hasOwnProperty(key)) { // self } else { // from the prototype chain } }
Object.getOwnPropertyNames
Return all (including non-enumerable) keys of the object (the original text said that it will find the prototype chain is wrong )
let obj = { key1: 'value1', key2: 'value2', key3: & # 39; value3 & # 39;, } Object.getOwnPropertyNames(obj).forEach(key => { let value = obj[key] })
Performance comparison
The following code uses the above methods to traverse the object with 1000000 attributes, looping 10 times
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 { 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] }) )
The following results are run by myself. The order means that the index is used directly when assigning values, and the random means that the key-value pairs are inserted with random numbers. The performance sorting obtained is the same as that of the author. Because both node.js and chrome are V8, this should also represent the performance ranking on the browser.
// order ;[ ['FORIN', 4677.321499], ['KEYS', 4812.776572], ['GETOWP', 8610.906197], ['VALUES', 9914.674390999999], ['ENTRIES', 19338.083694], ] // random ;[ ['KEYS', 4502.579589], ['FORIN', 4678.013548000001], ['GETOWP', 8880.325031999999], ['VALUES', 10104.106962], ['ENTRIES', 17089.637588999998], ]
I heard that the engine will guess the next value to make the operation faster, but the data does not seem to have much impact.
It can be regarded as a little dry goods, come to the original text to applaud the author
Recommended tutorial: “JS Tutorial”
The above is the detailed comparison of Javascript object iteration methods and performance For more content, please pay attention to other related articles on 1024programmer.com!