WebDevDude
WebDevDude

Reputation: 859

How does this function determine of an object is empty?

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

Answers (6)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276496

Why it works:

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.

Why it doesn't:

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.

What the docs say:

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.

What if you really want to check if an Object is empty?

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

The Spooniest
The Spooniest

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

epascarello
epascarello

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

iAmClownShoe
iAmClownShoe

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

theshadowmonkey
theshadowmonkey

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

Jake Zeitz
Jake Zeitz

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

Related Questions