Array.prototype.map.call против Array.map

1

Я читаю о методе querySelector, статья предполагает, что один из них должен использовать Array.prototype.map.call() вместо map(). У меня нет проблем с этим, однако я действительно не понимаю, почему Array.prototype.map.call() следует выбирать над Array.map() Что делает его лучше другого?

let nodes = document.querySelectorAll('div.menu-item')

Array.prototype.map.call(nodes, one => one.innerHTML)
//vs
Array.map(nodes, one => one.innerHTML)
  • 0
    Array.from(document.querySelectorAll('div.menu-item')).map(one => one.innerHTML) было бы лучше видеть в ES2015 (называть его ES6 - сложная привычка для выхода) ,
  • 0
    @ste2425: ste2425: еще лучше, используйте функцию сопоставления Array.from : Array.from(document.querySelectorAll('div.menu-item'), o‌​ne => one.innerHTML)
Показать ещё 4 комментария
Теги:
arrays
dom

2 ответа

1
Лучший ответ

Что делает его лучше другого?

В стандартной библиотеке JavaScript нет Array.map. Поэтому, если вы используете его, вы полагаетесь на неуказанную функцию, которая может присутствовать или не присутствовать во всех ваших целевых средах. (Firefox SpiderMonkey работает под управлением JavaScript, например, движок Chrome V8 на данный момент не работает.) Таким образом, это будет довольно существенная причина, чтобы предпочесть Array.prototype.map.call - из этих двух вариантов. :-)

Но, как указывает ste2425, учитывая использование функций let и arrow, вы, кажется, кодируете среду ES2015+. В этом случае (или если вы добавите полипол) вы можете использовать функции отображения Array.from:

let innerHTMLArray = Array.from(nodes, o‌​ne => one.innerHTML);

Array.from создает массив из любого объекта, подобного массиву или итерируемого объекта. NodeList от querySelectorAll одновременно. :-) И это необязательно позволяет вам сопоставлять значения по мере их выполнения.

Пример:

if (!Array.from) {
  console.error("Your browser doesn't support Array.from yet.");
} else {
  const htmlArray = Array.from(document.querySelectorAll("div.menu-item"), e => e.innerHTML);
  console.log(htmlArray);
}
<div>I'm not included in the result because I don't have the class</div>
<div class="menu-item">Menu item #1</div>
<div class="menu-item">Menu item #2</div>
<div class="menu-item">Menu item #3</div>
  • 0
    Аааа, теперь я вижу, я использую реагирование, поэтому, возможно, Бабель добавил все эти дополнительные функции. С пустой страницей в консоли Chrome Array.map не определен. Так добавлен ли Array.map() в стандарт es2015?
  • 0
    @XunYang: Нет. Как я уже сказал, она не является частью текущей стандартной библиотеки JavaScript - нет в ES2015, ES2016 или ES2017, и я не вижу никаких предложений для этого.
Показать ещё 8 комментариев
2

Во-первых, нет Array.map. Вариант использования для первого варианта следующий: вы не сможете ссылаться на map например, с помощью document.querySelectorAll('div')[0].map. Это связано с тем, что document.querySelectorAll возвращает NodeList а не массив и не имеет метода карты.

Что делает его лучше другого?

На самом деле вопрос не в том, какой вариант лучше. Речь идет о невозможности называть map в NodeList.

Большинство функций в прототипе массива могут обрабатывать объекты, подобные массиву (то есть объекты, ключи которых представляют собой числовые индексы), когда они передаются как thisArg для вызова (or apply). Hence, (or apply). Hence, Array.prototype.map.call(array-like, mapFunction) 'может отображать NodeList точно так же, как массив.

Однако есть две альтернативы:

  1. Используйте Array.from: Array.from(nodes, n => n.innerHTML) введенные в ES6 и не поддерживаемые в Internet Explorer. Однако, когда это не имеет значения, я бы предпочел это.
  2. Используйте Array.prototype.slice.call(nodes).map(n => n.innerHTML), который работает аналогично (см., Как работает Array.prototype.slice.call()?) Или придерживаться Array.prototype.map.call.

Однако в соответствии с вашим общим кодом использование (1) кажется совершенно прекрасным, и я, лично, предпочел бы это.

  • 0
    Как я уже сказал в своем ответе, если вы используете Array.from , немедленное использование map для результата бессмысленно и неэффективно. Просто используйте аргумент обратного вызова для Array.from .
  • 0
    @TJCrowder Хм, да, спасибо, я обновил ответ.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню