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

后端 未结 5 955
無奈伤痛
無奈伤痛 2020-12-30 04:37

I fell upon some lines of code where the guy uses Array.prototype.map.call instead of Array.map.call:

function getLinks() {
    va         


        
相关标签:
5条回答
  • 2020-12-30 05:02

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

    0 讨论(0)
  • 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.:)

    0 讨论(0)
  • 2020-12-30 05:21

    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
    0 讨论(0)
  • 2020-12-30 05:24

    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.

    0 讨论(0)
  • 2020-12-30 05:25

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

    0 讨论(0)
提交回复
热议问题