Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
74
Help us understand the problem. What is going on with this article?
@yugo-yamamoto

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"))
74
Help us understand the problem. What is going on with this article?
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.
Sign Up
If you already have a Qiita account Login
74
Help us understand the problem. What is going on with this article?