Help us understand the problem. What is going on with this article?

querySelectorAllで帰ってきたNodeListを外部ライブラリを使わずにforEachしたい

More than 3 years have passed since last update.

You Don't Need jQuery とは言うものの

You Don't Need jQuery をみて気になるのが、forEachの書き方。querySelectorAllで帰ってくるNodeListは配列ではなくオブジェクトなので、JavaScriptのforEachが使えない。

そこで登場するのが
Array.prototype.slice.call
これで、配列っぽいオブジェクトが配列扱いになるらしい。配列っぽいオブジェクトって何?

試しに文字列をいれてみる

Array.prototype.slice.call("ab") 
> ["a", "b"]

となる。ただ素のオブジェクトを入れても

Array.prototype.slice.call({0:"value1",1:"value2"}) 
> []

にしかならない。

試しに、lengthをもった、数字がキーのオブジェクトを作って、それを配列化してみよう

Array.prototype.slice.call({0:"value1",1:"value2",length:2}) 
> ["value1", "value2"]

期待通り。どうも、Length をみて、[0][1]と切り出しているだけっぽい。Lenghと添字アクセスが可能だから文字列が配列に変換できたっぽいね。ということで、手作業で配列っぽいオブジェクトは作れる。

本題のNodeListのforEach。

「ページの中のアンカーのhrefを全部出力するってワンライナー」はこうかける

Array.prototype.slice.call(document.querySelectorAll("a")).forEach( function(e){ console.log(e.href)})

長い。メソッド深すぎ、タイプ多すぎ。読みづらい。

配列に変換したいのではなく、foreEachを使いたいだけなんだから、一足飛びにforEachをcallしてみよう。foEachをCallすると、第一引数にNodeListを直接ぶち込んで、第二引数でcallbackを指定できる。

Array.prototype.forEach.call(document.querySelectorAll("a"), function(e){ console.log(e.href)})

ちょっと短くなった。sliceって単語が出てこないだけ見通しがいい。

いまどきのブラウザは、Arrow Function もサポートし始めているから、スペルミスの多いfunction は省略しちゃおう。

Array.prototype.forEach.call(document.querySelectorAll("a"), e => console.log(e.href))

さらに短くなった。Array.prototypeも面倒だ。prototypeが打ちづらい。

[].forEach.call(document.querySelectorAll("a"), e => console.log(e.href))

さらに短くなった。

ES6になると、配列化とmapの両方をやってくれる、Array.fromというメソッドがある。まぁ親切。これ最強。

Array.from(document.querySelectorAll("a"),  e => console.log(e.href))

手元の Chromeバージョン 50.0.2661.94 (64-bit)では動いている。

ちなみに第二引数で処理されるのはforEachではなくmapなので、returnすれば、配列に変換できる。

Array.from(document.querySelectorAll("a"),  e => {return e.href;})

「ページ内のアンカーのhrefを配列にして、それを改行でjoinして出力」くらいが事務用途で便利。
(コンソールからコピペした時に余計なものがついてこない)

console.log(Array.from(document.querySelectorAll("a"),  e => {return e.href;}).join("\n"))
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした