返回对象所有可枚举的键值对,不会追寻原型链上的 key
let obj = { key1: 'value1', key2: 'value2', key3: 'value3',}object.entries(obj).foreach(entry => { let key = entry[0] let value = entry[1] // entry 会是这样 ["key1", "value1"]})
object.keys
返回对象所有可枚举的键
let obj = { key1: 'value1', key2: 'value2', key3: 'value3',}object.keys(obj).foreach(key => { let value = obj[key]})
object.values
返回对象所有可枚举的值
let obj = { key1: 'value1', key2: 'value2', key3: 'value3',}object.values(obj).foreach(value => { // 只能使用 value})
for…in loop
迭代可枚举属性,会顺着原型链找下去
let obj = { key1: 'value1', key2: 'value2', key3: 'value3',}for (const key in obj) { let value = obj[key] if (obj.hasownproperty(key)) { // 本身的 } else { // 来自原型链的 }}
object.getownpropertynames
返回对象所有(包括不可枚举)的键(原文说会找原型链是错的)
let obj = { key1: 'value1', key2: 'value2', key3: 'value3',}object.getownpropertynames(obj).foreach(key => { let value = obj[key]})
性能比较
下面的代码用上面的几种方法遍历有 1000000 个属性的对象,循环 10 次
const { performanceobserver, performance } = require('perf_hooks')let objectsize = 1000000let iterations = 10console.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' + math.random()] = 'val' + math.random() } 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] }))
下面的结果是我自己跑的,顺序的是指赋值的时候直接用 index,随机则是键值对都插入随机数,得到的性能排序是和作者一样的,也因为 node.js 和 chrome 都是 v8,所以这个应该也是代表在浏览器上的性能排序。
// 顺序;[ ['forin', 4677.321499], ['keys', 4812.776572], ['getowp', 8610.906197], ['values', 9914.674390999999], ['entries', 19338.083694],]// 随机;[ ['keys', 4502.579589], ['forin', 4678.013548000001], ['getowp', 8880.325031999999], ['values', 10104.106962], ['entries', 17089.637588999998],]
之前听说引擎会猜测下一个值让运行速度更快,看数据似乎没有太大影响。
也算是一点干货,快点来原文给作者鼓鼓掌吧
推荐教程:《js教程》
以上就是javascript对象迭代方法和性能的比较的详细内容。
