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 newEach 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.

This exact behavior is well documented thus $.each behaves exactly as expected.
From http://api.jquery.com/jQuery.each/
Here a live test case to show what is happening.