77
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-05-07

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"))
77
77
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
77
77

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?