Почему Array.prototype.map.call вместо Array.map.call

Я упал на некоторые строки кода, где парень использует Array.prototype.map.call вместо Array.map.call:

function getLinks() {
    var links = document.querySelectorAll('h3.r a');
    return Array.prototype.map.call(links, function(e) {
        return e.getAttribute('href');
    });
}

Почему бы просто не называть Array.map.call? Я проверил на консоли Firefox, и обе функции Array и Array.prototype имеют функцию карты. Есть ли разница?

Ответ 1

Это связано с тем, что document.querySelectorAll не возвращает экземпляр Array, а экземпляр NodeList (или, по крайней мере, не гарантированно возвращает Array во всех браузерах). NodeList имеет индексированные элементы, но не включает все методы из прототипа Array.

Вот почему нам нужен метод hack, вызывающий map из прототипа Array в контексте возвращаемого объекта.

Я предполагаю, что вы понимаете, что для:

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

выражение:

a.map(f);

эквивалентно:

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

См. также:

Ответ 2

Потому что Array.map.call не работает. Array.map построен для принятия двух параметров: массива и обратного вызова. call запускает функцию, устанавливая ее this в объект, который вы поставляете.

Итак, когда вы запускаете Array.prototype.map.call(somearray,function(){...});, это практически то же самое, что вы вызывали somearray.map(function(){...});. Array.map - это просто метод утилиты. Javascript только в Firefox (еще одна причина, почему бы не использовать его) должен сделать жизнь проще. Функция Array.map не является межсерверной.

Изменить: Причиной того, что они должны были использовать Array.prototype.map.call(links,...); вместо просто links.map(...);, является то, что querySelectorAll не возвращает нормальный массив, он возвращает NodeList, который не имеют метод map.

Ответ 3

Вероятно, они избегали Array.map, потому что он не существует в Chrome или IE.

Ответ 4

map предназначен для вызова экземпляров массива. Таким образом, Array.prototype.map. Array.map не существует в большинстве браузеров.

Ответ 5

Хороший вопрос:

Массив - это функция-конструктор для создания массивов.


Если вы наберете Array в консоли браузера, вы получите определение функции, что-то вроде

function Array() {[собственный код]}

Хотя если вы наберете Array.prototype в консоли браузера, вы получите пустой массив i.e []  т.е. объект Array. Рассмотрим этот отрывок

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


Когда вы вводите d = new a();
Затем d - объект, имеющий два свойства, которые являются функциями, то есть b и c, и вы можете позвонить

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

Но вы не можете позвонить

a.b() or a.c()//, поскольку функция b и c не является свойством a.
Так так же, как функции b и c определены в функции a. Аналогично, функциональная карта определена в функции Array.

Таким образом, вы не можете вызывать Array.map(), но вам нужно получить объект Array и функцию вызова на нем.
Array.prototype дает нам объект Array
Поэтому они используют Array.prototype.map.call(a,func)

Извините за длительное объяснение. Надеюсь, что это принесет пользу.:)