forin 和 Object.entries 运行效率对比

我们从一个很简单的问题出发,怎么遍历一个 js 对象?第一种使用 forin,但是会遍历到原型链上的属性,这个不是我们想要的。

forin 存在的问题

var s = {a:1}
s.__proto__ = {b:2}
for(var i in s) {console.log(i)}

所以我们要这样判断一下。

var s = {a:1}
s.__proto__ = {b:2}
for(var i in s) { if(s.hasOwnProperty(i)) console.log(i)}

Object.entries 会更慢

如果不想使用 hasOwnProperty,可以使用 Object.entries

var s = {a:1}
s.__proto__ = {b:2}
for(var [k,v] of Object.entries(s)) { console.log(k)}

Object.entries 会比 forin 效率要低,但是低多少呢?我们看看下面的例子。

let data = {}
let length = 10 ** 6
let i = 0
let map = new Map()

for (; i < length; i += 1) {
  data[i] = i
  map.set(i,i)
}

console.time('forin')
for(let key in data){
  if(data.hasOwnProperty(key)){
    let value = data[key]
   // silence 
  }
}
console.timeEnd('forin')

console.time('entries')
let arr = Object.entries(data)
for(let [k, v] of arr){
  // silence
}
console.timeEnd('entries')

console.time('Map')
for(let [k, v] of map){
  // silence
}
console.timeEnd('Map')

似乎使用 Map 更好

2020-02-25 更新:

再看一下上面的例子,使用 Map,既不用做原型链属性的检测,也能更快的遍历。Map 是经过优化的,更应该推荐这种写法,或者说使用这种数据结构。

总结

在我机器上,Object.entries 的运行时间会比 forin 多 2-3 倍的时间,所以特别、极度、十分注重效率的话用 forin,否则的话代码更优雅一点。

扩展阅读

作者: 曾小乱

喜欢写点有意思的东西

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据