Reputation: 838
The code:
var content = Array.prototype.map.call(document.getElementsByTagName("p"), function(e) {
return e.innerHTML;
});
It's from p. 367 of JavaScript: The Definitive Guide, 6th ed.
Here's what I think is happening in this code.
The variable content
is being assigned the result of a .map()
call on the NodeList
of paragraph tags returned by document.getElementsByTagName("p")
.
The .map()
method is accessed from the Array.prototype
, and its this
value is set to be the paragraph tag NodeList
using .call()
. Since .map()
applies a function that has access to item, index, array
, the e
in function(e)
is the item of the NodeList
.
So the content
variable ends up being comprised of the result of .innerHTML
calls on each of the Element
type Nodes
in the NodeList
made up of paragraph tags in the current document.
.innerHTML
will return the text of a given HTML element if it has no other nodes inside it. Otherwise it will return the HTML nodes inside it.
Is that correct? I've tried:
Upvotes: 11
Views: 134
Reputation: 75317
Yup, that's exactly that's happening.
Just to be really picky:
.innerHTML
will return the text of a given HTML element if it has no other nodes inside it. Otherwise it will return the HTML nodes inside it.
.innerHTML
always returns the HTML contents of an element, regardless of whether it contains children or not. It's just hard to spot the difference between the text of an element and HTML of an element when it contains no children (but there is a difference!).
HTML:
<div><</div>
JS:
console.log(document.getElementsByTagName("div")[0].innerHTML); // "<"
console.log(document.getElementsByTagName("div")[0].textContent); // "<"
FWIW, this is possible in the first place because a lot of JavaScript methods prefer duck typing to relying on inheritance
When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck
Because of this, map()
will happily let you map()
any object which feels like an array (i.e. has a .length
property).
You could also have used:
var content = [].map.call(document.getElementsByTagName("p"), function(e) { return e.innerHTML; });
... but the former is preferred because you don't have to create, then throwaway, the array to get access to the map()
function.
Upvotes: 7