Join 3,374 readers in helping fund MetaFilter (Hide)


What's the non-WTF way to do this simple thing?
November 3, 2010 1:17 AM   Subscribe

Is there a concise way to test whether an ECMAscript object has had properties added since creation?

If I have
var foo = new Object;

// a bunch of code that may or may not end up executing
// foo[some_string_with_unpredictable_contents] = 'qux';
then it's easy enough to enumerate all the properties added to foo, if any, using a loop like
for (var i in foo) {
    DoSomethingWith(i, foo[i]);
}
But if all I want to do is test whether at least one property has in fact been added to foo - that is, if I want the equivalent of HasAtLeastOneProperty(foo), after defining
function HasAtLeastOneProperty(x) {
    for (var i in x) {
        return true;
    }
    return false;
}
then surely there must be some standard idiom for doing that without defining a cheesy little helper function?
posted by flabdablet to Computers & Internet (6 answers total)
 
if (foo.length) bar;
posted by beerbajay at 1:33 AM on November 3, 2010


Doesn't work, unfortunately.

foo.length doesn't even exist unless foo is created as foo = new Array; rather than foo = new Object; and even if I do that then foo.length always evaluates as zero unless at least one of the added properties has a name that can be coerced to a number.

That is, after
var foo = new Array;
foo['oink'] = 'squee';
then HasAtLeastOneProperty(foo) will return true as expected, but foo.length is still zero. If
foo['573'] = 'urgh;
then foo.length comes out to 574, which is nonzero and therefore fine. But since I can't guarantee that the contents of some_string_with_unpredictable_contents will look numeric, this doesn't work for me.
posted by flabdablet at 1:50 AM on November 3, 2010


Seems like you want Object.keys.length, unfortunately it's not available until ECMAScript5. The discussions on the implementation defect in Firefox may help.
posted by robertc at 3:16 AM on November 3, 2010


Ah, you're right. That's unfortunate.

In javascript 1.8.5 (Firefox 4), you can do: Object.keys(foo).length. The "compatibility" version on that page is essentially what you've written above.
posted by beerbajay at 3:21 AM on November 3, 2010


Thanks! I love AskMe.
posted by flabdablet at 4:36 AM on November 3, 2010


You may already know this, but don't forget about properties that already exist on the object, like 'length' for objects of Array or String type. A common error is to iterate through properties with for (var property in object) and not ignore the stuff already there (that got added to the prototype via framework, or whatever). The common idiom to deal with this is to use hasOwnProperty:
for (var property in object) {
   if (object.hasOwnProperty(property)) {
      //do stuff
   }
}
So you don't want the simple definition you posted earlier, but rather:
function HasAtLeastOneProperty(x) {
    for (var i in x) {
        if x.hasOwnProperty(i) return true;
    }
    return false;
}

posted by RikiTikiTavi at 8:10 AM on November 3, 2010


« Older Need clips discussing self est...   |  What contemporary American aut... Newer »
This thread is closed to new comments.