Ticket #7260 (closed bug: invalid)
$.each() fails on an object when the object has a key named 'length'
| Reported by: | lucas.madar@… | Owned by: | |
|---|---|---|---|
| Priority: | undecided | Milestone: | 1.5 |
| Component: | unfiled | Version: | 1.4.2 |
| Keywords: | Cc: | ||
| Blocking: | Blocked by: |
Description
If you have an object, like this:
var obj = { name: "something", length: 12, height: 32 };
and then you try to iterate over it using $.each:
$.each( obj, function( key, value ) {
...
} );
The inner function is never called because jquery treats the object as an array instead of an object. This behavior is unexpected; it should either be documented or fixed.
Change History
comment:3 Changed 2 years ago by anonymous
I fail to see how a json object with a quoted length property could be considered an array-like object.
comment:4 Changed 2 years ago by anonymous
This is also a problem in jQuery templates when using {{each}} to iterate through an object which happens to have a "length" key.
comment:5 Changed 2 years ago by jboesch
I think we can fix this issue. If jQuery.map is supporting objects in 1.6 (and works with length props) I think we should maybe consider adding it here.
Here is what the code is right now being used in jQuery.each (object/array detection):
isObj = length === undefined || jQuery.isFunction( object );
This can be changed to what's being used in jQuery.map (v 1.6):
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || jQuery.isArray( elems ) ) ;
Here's Dan's isArray var in action in the jQuery.map function: https://github.com/jquery/jquery/pull/299/files
Here's a fiddle with me changing that one line: http://jsfiddle.net/jboesch26/Ungsa/
This would allow looping over objects with length props. This newEach2 proposal seems to be slightly faster as well: http://jsperf.com/each-object-supporting-length-key/6
If this is cool, I'll make a pull request.
comment:6 Changed 2 years ago by jboesch
Pull request: https://github.com/jquery/jquery/pull/336/files
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

I think you misread the documentation. $.each behaves exactly as expected and as documented.
From http://api.jquery.com/jQuery.each/
This sentence covers your case, stating that objects with a length property (as in your example) are iterated by numeric index.
So if you remove/name the length property in your sample object $.each while behave as expected.
Here a live test case to show what is happening.