Я правильно понял этот код Function.prototype.call()?
Код:
var content = Array.prototype.map.call(document.getElementsByTagName("p"), function(e) {
return e.innerHTML;
});
Это из п. 367 JavaScript: окончательное руководство, 6-е изд.
Здесь я думаю, что это происходит в этом коде.
Переменной content
присваивается результат вызова .map()
в теге NodeList
тегов абзаца, возвращаемых document.getElementsByTagName("p")
.
Доступ к методу .map()
осуществляется из Array.prototype
, а его значение this
установлено как тег абзаца NodeList
, используя .call()
. Поскольку .map()
применяет функцию, имеющую доступ к item, index, array
, e
in function(e)
является элементом NodeList
.
Таким образом, переменная content
заканчивается состоянием результата .innerHTML
вызывает каждый из Element
тип Nodes
в NodeList
, состоящий из тегов абзаца в текущем документе.
.innerHTML
вернет текст данного элемента HTML, если в нем нет других узлов. В противном случае он вернет HTML-узлы внутри него.
Это правильно? Я пробовал:
- Чтение Документация MDN по функции .prototype.call
- Поиск программистов SE Я нашел Неверное понимание, которое я не уверен, как интерпретировать. Он утверждает, что документация MDN неполна.
- Чтение больше в книге окончательных версий.
- Беседа в JSFiddle - код действует так, как ожидалось, я просто хочу знать, как он делает то, что он делает.
Ответы
Ответ 1
Да, это именно то, что происходит.
Просто быть очень разборчивым:
.innerHTML
вернет текст данного элемента HTML, если в нем нет других узлов. В противном случае он вернет HTML-узлы внутри него.
.innerHTML
всегда возвращает содержимое HTML элемента, независимо от того, содержит ли он детей или нет. Просто трудно определить разницу между текстом элемента и HTML элемента, когда он не содержит детей (но есть разница!).
HTML:
<div><</div>
JS:
console.log(document.getElementsByTagName("div")[0].innerHTML); // "<"
console.log(document.getElementsByTagName("div")[0].textContent); // "<"
FWIW, это возможно в первую очередь потому, что многие методы JavaScript предпочитают утиную печать, полагаясь на наследование
Когда я вижу птицу, которая ходит как утка и плавает, как утка и шарлатанья, как утка, я называю эту птицу уткой
Из-за этого map()
с радостью предоставит вам map()
любой объект, который будет похож на массив (т.е. имеет свойство .length
).
Вы также могли бы использовать:
var content = [].map.call(document.getElementsByTagName("p"), function(e) { return e.innerHTML; });
... но первый предпочтительнее, потому что вам не нужно создавать, а затем выбросить массив, чтобы получить доступ к функции map()
.