Skip to content Skip to sidebar Skip to footer

Why Array.prototype.map.call Instead Of Array.map.call

I fell upon some lines of code where the guy uses Array.prototype.map.call instead of Array.map.call: function getLinks() { var links = document.querySelectorAll('h3.r a');

Solution 1:

This is because document.querySelectorAll does not return an Array instance but an instance of NodeList (or at least is not guaranteed to return an Array on all browsers). NodeList has indexed elements but does not include all methods from the Array prototype.

This is why we need a hack calling map method from Array's prototype in the context of the returned object.

I assume that you understand that for:

var a = [], f = function() {};

the expression:

a.map(f);

is equivalent to:

Array.prototype.map.call(a, f);

See also:


Solution 2:

Because Array.map.call doesn't work. Array.map is built to accept two parameters: the array, and the callback. call runs a function setting its this to the object you supply.

So, when you run Array.prototype.map.call(somearray,function(){...}); it is virtually the same as if you called somearray.map(function(){...});. Array.map is just a utility method Javascript in Firefox only (another reason why not to use it) has to make life easier. The Array.map function is not cross-browser.

Edit: The reason that they had to use Array.prototype.map.call(links,...); instead of just links.map(...);, is that querySelectorAll does not return a normal array, it returns a NodeList that does not have a map method.


Solution 3:

Good Question:

Array is a constructor function to create arrays.


If you type Array in browser console you will get a function definition, something like

function Array() { [native code] }

While if you type Array.prototype in browser console you will get an empty array i.e [ ] i.e. an Array object.

Consider this excerpt

function a(){
console.log('hi');
function b(){console.log('b');}
function c(){console.log('c');}
return {b:b,c:c,d:this}
}


When you type d = new a();
Then d is an object having two properties which are functions i.e. b and c and you can call

>> d.b() //logs b
>> d.c() //logs c

But you cannot call

a.b() or a.c() // since function b and c is not property of a.

So just as function b and c are defined in function a. Similarly function map is defined in function Array.

So you cannot call Array.map() but you have to get an object of Array and call map function on it.
Array.prototype gives us an Array object
Therefore they are using Array.prototype.map.call(a,func)

Sorry for long explanation. Hope it benefits.:)


Solution 4:

map is meant to be called on array instances. Thus, Array.prototype.map. Array.map doesn't exist in most browsers.


Solution 5:

They've probably avoided Array.map because it doesn't exist in Chrome or IE.


Post a Comment for "Why Array.prototype.map.call Instead Of Array.map.call"