Lets put this baby to bed; tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:
Bottom line performance wise, use:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
or
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Results under Node:
return (Object.keys(obj).length === 0)
for (var x in obj) { return false; }...
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
return ('{}' === JSON.stringify(obj))
Testing for Object with 0 keys 0.00018 0.000015 0.000015 0.000324
Testing for Object with 1 keys 0.000346 0.000458 0.000577 0.000657
Testing for Object with 2 keys 0.000375 0.00046 0.000565 0.000773
Testing for Object with 3 keys 0.000406 0.000476 0.000577 0.000904
Testing for Object with 4 keys 0.000435 0.000487 0.000589 0.001031
Testing for Object with 5 keys 0.000465 0.000501 0.000604 0.001148
Testing for Object with 6 keys 0.000492 0.000511 0.000618 0.001269
Testing for Object with 7 keys 0.000528 0.000527 0.000637 0.00138
Testing for Object with 8 keys 0.000565 0.000538 0.000647 0.00159
Testing for Object with 100 keys 0.003718 0.00243 0.002535 0.01381
Testing for Object with 1000 keys 0.0337 0.0193 0.0194 0.1337
Note that if your typical use case tests a non empty object with few keys, and rarely do you get to test empty objects or objects with 10 or more keys, consider the Object.keys(obj).length option. - otherwise go with the more generic (for... in...) implementation.
Note that Firefox seem to have a faster support for Object.keys(obj).length and Object.getOwnPropertyNames(obj).length, making it a better choice for any non empty Object, but still when it comes to empty objects, the (for...in...) is simply 10 times faster.
My 2 cents is that Object.keys(obj).length is a poor idea since it creates an object of keys just to count how many keys are inside, than destroys it! In order to create that object he needs to loop overt the keys... so why use it and not the (for... in...) option :)
var a = {};_x000D_
_x000D_
function timeit(func,count) {_x000D_
if (!count) count = 100000;_x000D_
var start = Date.now();_x000D_
for (i=0;i<count;i++) func();_x000D_
var end = Date.now();_x000D_
var duration = end - start;_x000D_
console.log(duration/count)_x000D_
}_x000D_
_x000D_
function isEmpty1() {_x000D_
return (Object.keys(a).length === 0)_x000D_
}_x000D_
function isEmpty2() {_x000D_
for (x in a) { return false; }_x000D_
return true;_x000D_
}_x000D_
function isEmpty3() {_x000D_
for (x in a) { if (a.hasOwnProperty(x)) return false; }_x000D_
return true;_x000D_
}_x000D_
function isEmpty4() {_x000D_
return ('{}' === JSON.stringify(a))_x000D_
}_x000D_
_x000D_
_x000D_
for (var j=0;j<10;j++) {_x000D_
a = {}_x000D_
for (var i=0;i<j;i++) a[i] = i;_x000D_
console.log('Testing for Object with '+Object.keys(a).length+' keys')_x000D_
timeit(isEmpty1);_x000D_
timeit(isEmpty2);_x000D_
timeit(isEmpty3);_x000D_
timeit(isEmpty4);_x000D_
}_x000D_
_x000D_
a = {}_x000D_
for (var i=0;i<100;i++) a[i] = i;_x000D_
console.log('Testing for Object with '+Object.keys(a).length+' keys')_x000D_
timeit(isEmpty1);_x000D_
timeit(isEmpty2);_x000D_
timeit(isEmpty3);_x000D_
timeit(isEmpty4, 10000);_x000D_
_x000D_
a = {}_x000D_
for (var i=0;i<1000;i++) a[i] = i;_x000D_
console.log('Testing for Object with '+Object.keys(a).length+' keys')_x000D_
timeit(isEmpty1,10000);_x000D_
timeit(isEmpty2,10000);_x000D_
timeit(isEmpty3,10000);_x000D_
timeit(isEmpty4,10000);
_x000D_