2008年9月20日土曜日

JavaScript における 3 つの for 文

1. for – 配列の要素を添字で順に参照

配列の要素を添字で順に参照する for 文。

例えば、「HTML の全 A タグを取得して、その内容を出力」する場合、以下のように書く。

anchors = document.getElementsByTagName('a');
for (var i=0; i<anchors.length; i++){
 console.log(anchors[i])
}

試しに `for each...in - JavaScript | MDN’ のページで、上記の文を Firebug のコンソールで実行する。結果は以下の通り。

<a href="#pageContent">
<a href="#searchInput">
<a title="メインページへ" href="/">
<a id="toolslink" href="#sitetools">
(略)
<a href="/index.php?title=Special:Article&type=backlinks&pageid=29784">
<a class="dismiss" onclick="return MTMessage.Hide();" href="#">
<a id="MTMessageDetailsLink" class="details" onclick="return MTMessage.ShowDetails(this);" href="#">

ページ中に含まれる 「A タグ」が全て出力されたことが分かる。

 

2. for each - 配列の要素の「値」を順に走査

添字を利用する for文を使わずに、配列の要素を順に走査したい for each 文を利用する。

for each...in – MDC によると、

指定された変数を、オブジェクトの全プロパティの値に対して反復します。異なるそれぞれのプロパティに対し、指定された文が実行されます。

この文は JavaScript 1.6 で作られた。

New in JavaScript 1.6 – MDC によると、

JavaScript 1.6 は Firefox 1.5 以降でサポートされています。

先ほどの例と同じページを対象にして、for each … in を試してみる。

anchors = document.getElementsByTagName('a');
for each(var p in anchors){
 console.log(p);
}

結果は以下の通り。

<a href="#pageContent">
<a href="#searchInput">
<a title="メインページへ" href="/">
<a id="toolslink" class="" href="#sitetools">
(略)
<a href="/index.php?title=Special:Article&type=backlinks&pageid=29784">
<a class="dismiss" onclick="return MTMessage.Hide();" href="#">
<a id="MTMessageDetailsLink" class="details" onclick="return MTMessage.ShowDetails(this);" href="#">
70
item()
namedItem()

あれ?さっきよりも、表示されるものが増えてしまった。 (@_@;)

 

HTMLCollection

例のコード内でアンカータグを取得するメソッドは、document.getElementsByTagName()。これによって返されるものは、HTMLCollection

Document Object Model HTML によると、

An HTMLCollection is a list of nodes. An individual node may be accessed by either ordinal index or the node's name or id attributes.

HTMLCollection は node のリスト。個々の node にはインデックスで参照できる。

HTMLCollection の定義を確認する。、(同上より)

interface HTMLCollection {
  readonly attribute unsigned long    length;
  Node               item(in unsigned long index);
  Node               namedItem(in DOMString name);
};

先ほどの出力の最後に表示さたもが、上記のプロパティに対応している。

出力内容は for each の説明にある通り、 HTMLCollection の全プロパティが表示されたということ。

 

3. for … in - 配列の要素の「値」を得る

for each  に似ていて、同じく全プロパティに対して走査するのが for … in 。

for...in – MDC によると、 for 文と同じく昔からあるようだ。同じく試してみると、

anchors = document.getElementsByTagName('a');
for (var p in anchors){
 console.log(p);
}

結果は、

0
1
2
3
(略)
67
68
69
length
item
namedItem

確かに for each に似ている。しかし、異なる点は、

for each...in - for...in に似ていますが、プロパティ名そのものではなく、オブジェクトのプロパティの値に対して反復します。 (同上より)

 

4. まとめ

追記 (2009.3.13) : JavaScript はハッシュが基本的な構造。 (cf. JavaScript のハッシュとオブジェクト)、

ハッシュの用語で言うなら、

  1. for ... in は「キー」を得られる。
  2. for each ... in は「値」を得られう。

と覚えておけばいい

var hash = {hoge:"ほげ", piyo:"ぴよ"}; 

// キーを走査
for (var key in hash){
    console.log(key);
} 

// 値を走査
for each (var val in hash){
    console.log(val);
}
結果は、
hoge
piyo
ほげ
ぴよ