While the interface of .map() method is .map( callback(index, domElement) ), it's $.map( array, callback(elementOfArray, indexInArray) ) for $.map()... Any idea over the reason why $.map() choose to place the returned arguments in an order such as value-index?
3 Answers
Because the API is imperfect. It started out inconsistent, but fixing that now would break existing code that uses $.map().
- http://bugs.jquery.com/ticket/5686: "There is no way to fix this and maintain backward-compatibility."
- http://bugs.jquery.com/ticket/7008: "The args are reversed but it would break a lot of code to change it."
2 Comments
$.map() was added in v1.0, but .map() wasn't added until v1.2. The moral of the story is that good API design is very hard, and perfect API design is pretty much impossible.If you study the jQuery API you will notice that all methods that work on a set of selected elements and accept callbacks, such as .each, .html, .text, etc., all pass the index of the element as first argument, i.e. .map is in line here. Usually you access the current element with this inside the callback, this is just a common pattern in jQuery and so the developers might have decided that it is more important to have the index as first argument.
On the other hand, the native Array.prototype.map method passes the value of element as first argument to the callback, so it seems to make sense that $.map works the same way, since it is supposed process a generic set of items.
1 Comment
Yes there is a difference between jQuery().map() and jQuery.map().
To outline some differences:
jQuery.map() = this tends to iterate over generic collection
jQuery().map() = Array-like objects must be cast to Arrays (.makeArray())
jQuery.map() = predominantely used for getting or setting the value of a collection of elements and returning that new Array
Also .map() is an ECMAScript5 function, and defined outside of jQuery (though implemented). One wonders if jQuery().map() was an older implementation. .map() is apparently faster!
John Resig states, "jQuery.map is primarily designed to be used with arrays of DOM elements (as outlined in the documentation). For this reason it does things like strip out null/undefined and it flattens arrays of nodes into a single array." This is as defined in ECMA (Mozilla). The other implementation is Resig's himself, hence the difference. That's not poor design!!!!!! Read
Second reason: "It's not as simple as just "fixing it"... jQuery.map's callback has param order that matches Array.prototype.map, while jQuery.fn.map's param order matches all other jQuery object iterator callback param order. Changing to one or the other would break backwards compatibility, which jQuery takes great pains to avoid" Read
.mapimplicitly flattens nested arrays as well.