The map function comes from JavaScript’s functional programming roots: it applies a function to every array element and returns a new array of the results without mutating the original array. So lets look at the native JS and jQuery map implementations.
Array.prototype.map
The signature for the native JS implementation is:
array.map(callback, thisObject)
The callback is the transforming function that changes elements of array into new elements while thisObject will be this inside the callback (some cool applications exist). Most browsers allow Array.protototype.map (support got added in JavaScript 1.6) however a few browsers still do not.
jQuery’s map
The signature for the jQuery implementation is:
$.map(array, callback, arg)
The array and callback parameters mean the same as above while the arg parameter allows you to send in extra arguments into the function ( I still haven’t found a use for this yet). Unfortunately this inside the callback refers to the Global object (Window); if you need to get around this, you can wrap the callback in a $.proxy call.
What’s the Callback?
The callback function is triadic in both implementations; the three parameters being the array element, the element’s index and the entire array (why this is needed still puzzles me).
jQuery callback example
var numbers = [1,2,3,4], squareNumbers = function (number) { return number * number; }, squares = $.map(numbers, squareNumbers); console.log(squares);//logs [1,4,9,16]
Array.prototype.map callback example
var numbers = [1,2,3,4], squares = numbers.map(squareNumbers); console.log(squares);//logs [1,4,9,16]
Using element indices
If the element indices matter to you, take it into consideration the subtle differences between both implementations.
jQuery example
The jQuery’s map method will always return a flattened array which does not contain null/undefined values.
var numbers = [1,2,3,4], getAllEvenIndices = function(number, indexInArray){ if(indexInArray % 2 === 0) return number }, evenIndexedNumbers = $.map(numbers, getAllEvenIndices); console.log(evenIndexedNumbers); //logs [1,3]
Native JS map example
The native implementation does not filter out undefined values.
var numbers = [1,2,3,4], evenIndexedNumbers = numbers.map(getAllEvenIndices); console.log(evenIndexedNumbers); //logs [1, undefined, 3, undefined]
Can I use Objects?
Surprisingly yes! You can call the jQuery.Map function on an object, for example, you have a JSON payload coming in from the server and you want an array of the values or keys, it is simple and easy to do this:
var payload = { id : 1, username : "xyz", points : 10} retrieveKeys = function (value, key) { return key; }, payloadKeys = $.map(payload, retrieveKeys); console.log(payloadKeys);//logs ["id", "username", "points"]
I don’t know of any simple way to do this using the native JS Array.prototype.map (I don’t know if it is even possible, maybe with some JS kung-fu. :) ).
So why use jQuery’s array.map if the JS language supports it implicitly? Here are a couple of reasons: the jQuery version strips off both undefined and null values, will work fine in all browsers (IE7 + IE8 do not have native support). But you can always write a polyfill too…
Here’s a puzzler: what would the snippet below return?
var result = $.map ([[1,2], [3,6]], function(elem) { return elem; })
Did you enjoy this post? Check out my other posts on JS, JS Events and JS functional Programing.
sure did,only that i am not in for any of the above(jS+jQ) but In shaa Allaah i get my hands on them smday.JazaakumuLlaahu khaeran wa baarakaLlaahu feeh
LikeLike
Ameen wa iyyaakum; please do let me know when you want to start.
LikeLike
As always Abdul, well done!
Re: Using nativeJS to get the keys with Kung Fo
there’s actually a method for that but it only works in the more recent/modern browsers –
Only makes sense to use this if you’re absolutely sure only modern browsers will be used (ideal and kinda rare). Otherwise, let jQuery do the work for you even when Object.keys() not supported by the browser.
LikeLike
Thanks a lot Oga Femi! Thanks for the motivation! :) It’s a honour to have you read my posts!
Aah, my write-up wasn’t clear enough (I should update it) – I was wondering if it was possible to use the Array.prototype.map method on Objects. Something along the lines of Array.prototype.map.bind, please do you know if this is possible?
The Object.Keys method is cool – EcmaScript 5 has lots of goodies :); have you tried the Object.getOwnPropertyNames? I found out that it allows you to iterate over non-enumerable values.
Thanks a lot once again!
LikeLike
Reblogged this on Sutoprise Avenue, A SutoCom Source.
LikeLike