JavaScript object literal length === undefined?

49,024

Solution 1

JavaScript object simply do not have a length property, only Arrays do. If you want to know the number of properties that are defined on a object, you have to iterate over them and count them.

Also, your for in loop is prone to bugs due extension of Object.prototype since in will traverse the complete prototype chain and enumerate all the properties that are on the chain.

Example

// Poisoning Object.prototype
Object.prototype.bar = 1;

var foo = {moo: 2};
for(var i in foo) {
    console.log(i); // logs both 'moo' AND 'bar'
}

You have to use the hasOwnProperty method on the object in order to filter out those unwanted properties.

// still the foo from above
for(var i in foo) {
    if (foo.hasOwnProperty(i)) {
        console.log(i); // only logs 'moo'
    }
}

Many JavaScript frameworks out there extend the prototype, not using hasOwnProperty often leads to horrible bugs.

Update

Concerning the actual problem that your code is not animation both properties.

for(var p in properties) {
    ...
    for(var i = 0; i <= frames; i++)
    {
        setTimeout((function(exti, element) {
            return function() {

                // p gets overriden by for outer for in loop
                element.style[p] = original + (pixels * exti) + 'px';
            }

        // you need to pass in a copy of the value of p here
        // just like you do with i and element
        })(i, element), i * (1000 / 60), element);
    }
    ....
 }

Solution 2

This is supported in node.js and newer environments.

var obj = {a: "a", b: "b"};
Object.keys(obj).length // 2

Solution 3

If you are using Underscore.js, you can use _.size():

_.size({one : 1, two : 2, three : 3});
=> 3
Share:
49,024
Olical
Author by

Olical

Drinker of (single malt scotch) whiskies, programmer of languages with (lots (of parenthesis)) and (ab)user of strange text editors / keyboards.

Updated on May 03, 2020

Comments

  • Olical
    Olical about 4 years

    I am working on this animation function but I have a problem. I can't seem to perform what should be an easy task, I can not get the length of an object. If you check out that jsFiddle you can see that I am running alert(properties.length); and it is returning undefined. Can anyone see why this might be?

  • Ivo Wetzel
    Ivo Wetzel over 13 years
    Use hasOwnProperty, please.
  • Martin Jespersen
    Martin Jespersen over 13 years
    On the same count alot of libraries out there (like jQuery) will fall apart horribly if you extend object.prototype, so if you use one of them hasOwnProperty is just a waste of cpu cycles.
  • Ivo Wetzel
    Ivo Wetzel over 13 years
    @Martin Jespersen So you sell of the code with "WARNING DO ONLY USE WITH FRAMEWORKS A, B AND C" printed on them? Sorry, but using hasOwnProperty is* a good practice.
  • Martin Jespersen
    Martin Jespersen over 13 years
    nope i am just tired of a web filled with javascript code that is so far from being optimized that even chrome chokes on it, then again, i guess i should be thankful since i make my money cleaning up the mess others make :P
  • Olical
    Olical over 13 years
    I really don't understand what you are getting at with the whole hasOwnProperty thing. I did not know I was setting a prototype?
  • Olical
    Olical over 13 years
    Why, how? Where does hasOwnProperty apply to this?
  • Ivo Wetzel
    Ivo Wetzel over 13 years
    @Martin Then go never use jQuery again, it's filled with calls to hasOwnProperty. What you are doing is premature optimization, nothing else.
  • Ivo Wetzel
    Ivo Wetzel over 13 years
    @Wolfy I just wanted to point out a possible bug that might happen when other code (be it yours you write in 2 weeks) or another script that you might use on your page extends the prototype, since then strange things will end up in your properties object.
  • Olical
    Olical over 13 years
    @Ivo Wetzel Oh right, I thought it was a problem with my current code. And I thought that my script was not working due to the length not existing and the for in statement not working because of it. So now I know there is nothing wrong with the object, do you know why it is only animating the height rather than both?
  • Martin Jespersen
    Martin Jespersen over 13 years
    @Ivo easy... your example is fine and you are right it has both suspenders and belt, nothing wrong with it, i was just peddling a simpler and faster alternative - don't take it personal that we have differing opinions ;)
  • Ivo Wetzel
    Ivo Wetzel over 13 years
    @Wofly You need to pass p into the animation wrapper too, just like i and element since the for in loop will otherwise override the p.
  • Olical
    Olical over 13 years
    @Ivo Of course! Because I have functions within functions. Thank you for that!
  • Alexandr
    Alexandr over 13 years
    Array-like objects also have length property:))) But they are not arrays.
  • Ivo Wetzel
    Ivo Wetzel over 13 years
    @Alexandr Indeed, but it was trying to avoid even more confusion here, it should also be noted that the only real JS object that behaves "like" an array is arguments. The rest is part of the DOM :)
  • Alexandr
    Alexandr over 13 years
    @Ivo Wetzel Of course your answer - is excelent! And it's absolutely enough to understand the reason of the problem.
  • Jamund Ferguson
    Jamund Ferguson over 12 years
    Better to just not update Object.prototype? Who does that? This is actually a great example!
  • Junaid Qadir Shekhanzai
    Junaid Qadir Shekhanzai over 12 years
    @IvoWetzel an example would be appreciated. I've used Martin Jespersen's answer here jsfiddle.net/jeykeu/qAH48 Is it the way to go?
  • RaphaelDDL
    RaphaelDDL about 10 years
    I'm yet to see the source but I hope that size() takes hasOwnProperty into account.
  • Igor Parra
    Igor Parra over 9 years