I fell upon some lines of code where the guy uses Array.prototype.map.call
instead of Array.map.call
:
function getLinks() {
va
map
is meant to be called on array instances. Thus, Array.prototype.map
. Array.map
doesn't exist in most browsers.
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 calla.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.:)
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:
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.
They've probably avoided Array.map
because it doesn't exist in Chrome or IE.