Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why Array.prototype.map.call instead of Array.map.call

Tags:

javascript

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');
    return Array.prototype.map.call(links, function(e) {
        return e.getAttribute('href');
    });
}

Why not simply calling Array.map.call? I checked on the Firefox console and both Array and Array.prototype have the map function. Is there a difference ?

like image 322
PerrierCitror Avatar asked Nov 22 '13 19:11

PerrierCitror


People also ask

What is array prototype map call?

Array.prototype.map() The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

What is the difference between the map and the for each method on the array prototype in JavaScript?

The map() method creates an entirely new array. The forEach() method returns “undefined“. The map() method returns the newly created array according to the provided callback function. The forEach() method doesn't return anything hence the method chaining technique cannot be applied here.

What is the difference between map () and forEach () methods on the array prototype?

The main difference between map and forEach is that the map method returns a new array by applying the callback function on each element of an array, while the forEach method doesn't return anything.

For which purpose the array map () method is used?

map() creates a new array from calling a function for every array element. map() calls a function once for each element in an array. map() does not execute the function for empty elements.


2 Answers

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:

  • Why does document.querySelectorAll return a StaticNodeList rather than a real Array?
  • https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll
  • https://developer.mozilla.org/en-US/docs/Web/API/NodeList
like image 186
Tomasz Gawel Avatar answered Sep 19 '22 05:09

Tomasz Gawel


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.

like image 32
Robbie Wxyz Avatar answered Sep 22 '22 05:09

Robbie Wxyz