为什么Object.keys比hasOwnProperty更快?

31
 // hasOwnProperty approach 
 for (key in obj) {
  if (obj.hasOwnProperty(key)) {
    value = obj[key];
  }
}

// Object.keys approach 
keys = Object.keys(obj);
for (i = 0, l = keys.length; i < l; i++) {
  value = obj[keys[i]];
}
根据 jsperf 的测试结果,Object.keys 方法比 hasOwnProperty 方法快50%以上。http://jsperf.com/object-keys-vs-hasownproperty/45为什么会出现这种情况呢?

你的测试可能不是你所期望的,一个简单的优化就可以解决:keys = Object.keys(obj); value = obj[keys[keys.length - 1]];绕过了你的循环。在第一个测试中,它会在每个循环中进行一次检查,而第二个测试只是用值填充变量。 - Hacketo
显然,普通的 for in 循环需要比 Object.keys 做更多的工作,此外,过滤 hasOwnProperty 更是更加繁琐的工作。 - Bergi
1
可能是因为Object.keys只被调用一次,而hasOwnProperty被调用多次(每个可枚举属性和每个不可枚举属性都会调用一次)。更多的函数调用意味着更慢的代码。此外,Object.keys是一个本地函数。因此,很有可能比JavaScript shim更快。 - Aadit M Shah
另一个更简单的测试在这里:https://jsperf.com/hasownproperty-vs-vs-in。似乎使用[]检查“truthy”值比使用inhasOwnProperty快得多。 - icl7126
为了我的心理健康,有没有人能够提供确认(最好附带来源),证明结果两种方式都是相同的? - krubo
2个回答

84
  • Object.keys查找所有自有的可枚举的属性(哦,而且数组很快)。
  • for in另外还会查找继承的可枚举的属性,而不仅仅是自己的。
  • for in+hasOwnProperty还会测试所有查找到的属性是否为自有属性。

即使没有继承的可枚举属性,使用这些方法也比不使用更加繁琐。


7
你的回答清晰易懂。 - Alan Dong

5
在那个帖子中的大部分测试显示hasownpropertyObject.keys()更快。然而,对于那些测试,要循环遍历的属性数量很少(小于20个属性)。
无论对象属性的数量多少(没有确切的数字,测试结果显示超过100个键时Object.keys()明显更好),Object.keys()都胜出。
请参见https://jsperf.com/object-keys-vs-hasownproperty/55。您可以转到页面底部查看所有测试的修订版。

我不知道怎么回事,但是从第47个版本开始,它显示'hasOwnProperty'是最快的。9,809,798比3,712,304。 - blissfool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接