Permalink
Browse files

Make sure that empty nodelists continue to map properly. Fixes #8993.

  • Loading branch information...
1 parent 86aa764 commit 6c449fd5df3e0ec50e893d055da9aea486e7d71c @jeresig jeresig committed May 2, 2011
Showing with 8 additions and 2 deletions.
  1. +1 −1 src/core.js
  2. +7 −1 test/unit/core.js
View
@@ -720,7 +720,7 @@ jQuery.extend({
i = 0,
length = elems.length,
// jquery objects are treated as arrays
- isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || jQuery.isArray( elems ) ) ;
+ isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
// Go through the array, translating each of the items to their
if ( isArray ) {
View
@@ -653,7 +653,7 @@ test("first()/last()", function() {
});
test("map()", function() {
- expect(7);
+ expect(8);
same(
jQuery("#ap").map(function(){
@@ -694,6 +694,12 @@ test("map()", function() {
});
equals( mapped.length, scripts.length, "Map an array(-like) to a hash" );
+ var nonsense = document.getElementsByTagName("asdf");
+ var mapped = jQuery.map( nonsense, function( v, k ){
+ return v;
+ });
+ equals( mapped.length, nonsense.length, "Map an empty array(-like) to a hash" );
+
var flat = jQuery.map( Array(4), function( v, k ){
return k % 2 ? k : [k,k,k];//try mixing array and regular returns
});

18 comments on commit 6c449fd

Contributor

rkatic replied May 2, 2011

The problem of simply adding length === 0 is that now even functions with no args (length == 0) will be traversed as arrays.
I know there is no such unit test (to add?), but $.each has.

Owner

timmywil replied May 2, 2011

@rkatic: I'm not sure what you mean. Passing a function to map?

So I guess John isn't in favor of isArrayLike either?

Contributor

rkatic replied May 2, 2011

@timmywil: Yes. Like in $.each.

@kflorence: Maybe because of number of lines?

Owner

timmywil replied May 2, 2011

Not trying to be difficult, but you mean iterate a function? A code example would help me understand.

Also, we tabled isArrayLike for 1.7. I'm not sure John's had time to review the matter.

Contributor

rkatic replied May 2, 2011

Yes. For example $.map( MyClass, handleStatics ).

EDIT: Probably not a big deal. Probably I am just a consistency-freak...

Owner

timmywil replied May 2, 2011

Hmm, I don't think that's a valid use case either for map or for each. I think iterating an instance(as in the case of a jQuery object) would be workable, but not a raw function.

Contributor

rkatic replied May 2, 2011

$.each does supports iterating functions. Just look in $.each code and you will see isObj = length === undefined || jQuery.isFunction( object );.
Also there is a respective unit test for $.each.

Owner

timmywil replied May 2, 2011

OK. I thought you were suggesting there was a regression in map.

Contributor

rkatic replied May 2, 2011

As I said, probably I am just a consistency-freak...

and for that I am glad that isArrayLike will be considered. :)

Owner

timmywil replied May 2, 2011

fair enough :)

As I said, probably I am just a consistency-freak...
and for that I am glad that isArrayLike will be considered. :)

Me too. Glad to hear it will be considered in 1.7!

Contributor

jboesch replied May 3, 2011

I'm kinda glad this is consistent. I know we don't say that jQuery.map supports node lists in the docs, but we had a unit test in core.js that mapped through node lists. This should have either been removed from the unit tests (if we chose not to support node lists) or added support to empty node lists.

Contributor

rkatic replied May 3, 2011

@jboesch: Rarely you can say that a documentation is also a specification for something. First one is generally a more user-friendly version of the second.
In case of jQuery, documentation is certainly not the specification. Is it needed? Maybe, but it is not simple in case of jQuery... but unit tests are pretty close.

EDIT: Also, i think NodeList are also objects. Why you think it have to be explicitly mentioned to be supported?

Contributor

jboesch replied May 3, 2011

@rkatic: The docs are the only specification there is at the moment (that I'm aware of). All I'm sayin' is that I think jQuery should either support node lists and go all out (which means handling the empty node lists properly and documenting it), or don't support node lists at all.

Contributor

rkatic replied May 3, 2011

As I updated my previous comment: Why NodeLists have to be explicitly mentioned if those are also objects?

Contributor

jboesch replied May 3, 2011

A node list looks like an object, but technically, it's a node list (with an item method).
You're right about being able to handle them like objects though. Maybe it doesn't need to be documented. shrug

Contributor

rkatic replied May 3, 2011

For users, it probably don't have to be mentioned (it's a documentation). For developers there are unit tests (+docs) :)

Please sign in to comment.