Почему 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)
Извините за длительное объяснение. Надеюсь, что это принесет пользу.:)