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?

- 39,703
- 12
- 54
- 77
-
2possible duplicate of [Length of Javascript Associative Array](http://stackoverflow.com/questions/5223/length-of-javascript-associative-array) – ripper234 Jan 31 '12 at 10:15
5 Answers
This is supported in node.js and newer environments.
var obj = {a: "a", b: "b"};
Object.keys(obj).length // 2

- 16,721
- 3
- 42
- 50
-
Not support in IE8, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys#Browser_compatibility – Igor Parra Feb 23 '15 at 18:33
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);
}
....
}

- 46,459
- 16
- 98
- 112
-
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. – Martin Jespersen Jan 14 '11 at 11:33
-
@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. – Ivo Wetzel Jan 14 '11 at 11:35
-
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 – Martin Jespersen Jan 14 '11 at 11:36
-
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 Jan 14 '11 at 11:38
-
3@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 Jan 14 '11 at 11:39
-
@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. – Ivo Wetzel Jan 14 '11 at 11:40
-
@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? – Olical Jan 14 '11 at 11:42
-
@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 ;) – Martin Jespersen Jan 14 '11 at 11:43
-
1@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`. – Ivo Wetzel Jan 14 '11 at 11:47
-
@Ivo Of course! Because I have functions within functions. Thank you for that! – Olical Jan 14 '11 at 11:50
-
Array-like objects also have length property:))) But they are not arrays. – Alexandr Jan 14 '11 at 12:09
-
@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 :) – Ivo Wetzel Jan 14 '11 at 12:18
-
@Ivo Wetzel Of course your answer - is excelent! And it's absolutely enough to understand the reason of the problem. – Alexandr Jan 14 '11 at 12:33
If you are using Underscore.js, you can use _.size()
:
_.size({one : 1, two : 2, three : 3});
=> 3

- 691
- 1
- 9
- 29

- 2,025
- 3
- 20
- 22
-
I'm yet to see the source but I hope that `size()` takes `hasOwnProperty` into account. – RaphaelDDL Apr 10 '14 at 18:32
Objects have no length, you'll need to use an array if you want that.
If you have to find the number of properties in an object there is only one way:
var length =0;
for(var i in obj) length++;

- 25,743
- 8
- 56
- 68
-
9
-
1
-
Better to just *not* update Object.prototype? Who does that? This is actually a great example! – Jamund Ferguson Mar 06 '12 at 17:56
-
@IvoWetzel an example would be appreciated. I've used Martin Jespersen's answer here http://jsfiddle.net/jeykeu/qAH48/ Is it the way to go? – Junaid Qadir Shekhanzai Mar 13 '12 at 06:03
Here's @Junaid Qadir Shekhanzai's general function for "finding the length of an object" (which as we're told, should properly be called "counting the properties of an object"). It combines solutions from @Ivo Wetzel and @Martin Jespersen:
function countProperties(myObj){
var length = 0;
if(typeof myObj != 'object'){
return false;
}
for(var i in myObj) {
length++;
}
return length;
}

- 999
- 9
- 27