Reputation: 859
I was digging around the jQuery source code and I found that they use this little code snippet to detect if a JavaScript object is empty.
function isMyObjEmpty( obj ) {
var name;
for (name in obj ) {
return false;
}
return true;
}
Can someone explain to me why this works? I just don't understand why this would ever return true.
Upvotes: 8
Views: 521
Reputation: 276496
This uses a for... in
loop to iterate through the object's properties.
If the object has any property, it would enter the loop and return false
If the object has no properties, it would not enter the loop, and return true
.
Note that there exists a case where it does not work. for.. in
loops only go through enumerable
properties so technically an object can be non-empty and it would still return false. One can define a property to not be enumerable and trick this method. Here is the problematic case.
The correct thing to say is that this method checks if an object has any enumerable properties.
You can find the method's documentation here.
Description: Check to see if an object is empty (contains no enumerable properties).
I personally find it odd they would call that method isEmptyObject
. I think a better suited name would be hasNoEnumerableProperties
.
In newer implementations of JS one can use Object.getOwnPropertyNames
. getOwnPropertyNames
gets all the properties, enumerable or not.
You can implement isMyObjEmpty
with Object.getOwnPropertyNames(myObject).length===0
. This checks that the object has no properties, enumerable or not.
This however, does not check prototypical properties though. This might, or might not be desirable behavior, you can check the discussion I've had with theshadowmonkey about it. That could be easily solved by making a call to Object.getPrototypeOf
recursively and checking for properties across the prototypical chain.
Upvotes: 16
Reputation: 2873
The key is that the for..in loop iterates over every property of the object, but nothing else. If there's nothing in the object at all, then that loop will never run, and so the "return false" line never gets executed. The program then moves on to the next line, which tells it to return true.
(This leads to an interesting question itself. Should that for..in loop be wrapped up in a hasOwnProperty() check? Or does the function actually intend to catch non-own properties and count the object as nonempty on that basis?)
Upvotes: 0
Reputation: 207537
When will it return true, when the object is empty of course.
isMyObjEmpty({});
how does it work? By using for...in
for...in
Summary
Iterates over the enumerable properties of an object, in arbitrary order. For each distinct property, statements can be executed.
So if there are no properties, it will not go into the for in loop. The the loop really should be checking for hasOwnProperty()
since that can lead to a false positive.
Upvotes: -1
Reputation: 616
Maybe not, but I'm assuming that the confusion comes from the key "name" in obj. It's not actually looking for a key called name in the object, rather any keys in the object are being assigned to a variable that they have called name. therefore, if it finds anything in the object, it will return false and confirm that it is indeed not an empty object. But if it finds nothing in the object, it will return true meaning that your object is empty.
Upvotes: 0
Reputation: 679
Try this. I think this is because of the object's own properties. You need to have hasOwnProperty to make sure you don't access its prototypes properties.
function isMyObjEmpty( obj ) {
var name;
for (name in obj ) {
if(obj.hasOwnProperty(name)) {
return false;
}
}
return true;
}
Read the document and see the implications written there.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/for...in
Upvotes: 0
Reputation: 2564
If it finds name
in obj
then there is something in the obj and it is not empty, if it cannot do that it will return true, saying the obj is empty
Upvotes: 1