for in と Object.keys

for (var key in obj) {
  if (obj.hasOwnProperty(key) {
    ...
  }
}

っていうのは

Object.keys(obj).forEach(function(key) {
  ...
});

と等価。

ベンチマークとってみた。環境はnode.js v0.4.7。
ベンチマークのコードはこんな感じ。一応hasOwnPropertyなしのfor inもはかる。

var Benchmark = require('benchmark');
var suite = new Benchmark.Suite;
var len = process.argv[2] || 100;

var obj = {};
while(len--) {
  obj['key' + len] = 'val' + len;
}

suite
.add('for in', function() {
  var key, val;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) {
      val = obj[key];
    }
  }
})
.add('for in (not call hasOwn)', function() {
  var key, val;
  for (key in obj) {
    val = obj[key];
  }
})
.add('Object.keys', function() {
  Object.keys(obj).forEach(function(key) {
    var val = obj[key];
  });
})
.on('cycle', function(event, bench) {
  console.log(String(bench));
})
.on('complete', function() {
  console.log('');
  var baseStats = this.filter('slowest')[0].stats;
  var base = baseStats.mean + baseStats.moe;
  this.each(function(obj) {
    var per = Math.round(base / ( obj.stats.mean + obj.stats.moe ) * 100);
    console.log('%s: %d%', obj.name, per);
  });
})
.run(true);

プロパティの数が1個のとき。for inのが早い。

$ node bench.js 1
for in x 8,593,762 ops/sec ±4.55% (84 runs sampled)
for in (not call hasOwn) x 22,707,368 ops/sec ±0.51% (86 runs sampled)
Object.keys x 2,674,276 ops/sec ±0.36% (87 runs sampled)

for in: 308%
for in (not call hasOwn): 848%
Object.keys: 100%

プロパティの数が1000個のとき。Object.keysのが早い。

$ node bench.js 1000
for in x 2,980 ops/sec ±1.83% (56 runs sampled)
for in (not call hasOwn) x 4,033 ops/sec ±3.23% (74 runs sampled)
Object.keys x 5,074 ops/sec ±1.37% (83 runs sampled)

for in: 100%
for in (not call hasOwn): 134%
Object.keys: 171%

プロパティの数が10000個のとき。Object.keysのが25倍くらい早い。

$ node bench.js 10000
for in x 21.64 ops/sec ±0.69% (21 runs sampled)
for in (not call hasOwn) x 415 ops/sec ±0.70% (84 runs sampled)
Object.keys x 528 ops/sec ±0.80% (84 runs sampled)

for in: 100%
for in (not call hasOwn): 1918%
Object.keys: 2437%

プロパティの数が多くなるとhasOwnPropertyの呼び出しコストがかかるよね、やっぱ。でもhasWonPropertyなしでもObjkect.keysのが早いね。

追記: 2011-02-05
http://d.hatena.ne.jp/hokaccha/20120205/1328452334