スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

[JavaScript] for-in構文にはご用心

JavaScriptで配列の要素全てを列挙したりする際には、for-in構文なんてのが便利なのですが、今回はそのfor-in構文に(というより機能拡張ウンヌンで)苦しめられましたのでメモしておきます。
(for-in構文:PerlやPHPでいうところのforeach構文です)
[2011.03.11追記]:勘違いしていたことがあるようで、この記事の下部に追記しました!

JavaScriptで配列を定義して、その全要素を列挙する際、以下のようにすればできます。
(もちろん他の方法もあります。)
// 配列変数の宣言
var ary = new Array( 10, 20, 30, 40, 50 );

// 順番にアラートを出す
for( i in ary ) {
    alert( i );
}

これを実行すると、アラートダイアログが5回連続で出るはずです。

そんな便利なfor-in構文なので、今回作っているものでも利用していました。

しかし、実はこれにはちょっと厄介なことが含まれます。


prototype.jsを使っているとマズイ

まず何が起きたかですが、

なんかヤケに多く回ってない??

...という現象です。明らかに配列の要素数より多くループしている様子でした。

<script type="text/javascript">
<!--
var ary = new Array();
for( i in ary ){
    alert( i );
}
-->
</script>

これを実行すると要素が列挙されますが、要素と言ってもnewしたばかりですから、
何も入っていません(と思いますよね。。。)

そこで実際に実行してみると、確かにアラートも何も出ません。(ぇ



しかし、問題はここからです...

<script type="text/javascript" src="./prototype.js"></script>
<script type="text/javascript">
<!--
var ary = new Array();
for( i in ary ){
    alert( i );
}
-->
</script>
(これは実行しないでください。40回くらいアラートが出ちゃいますよ^^;)

Ajaxなんかを便利に扱える、おなじみprototype.jsを読み込んだだけですが。。。
これを実行すると、下に挙げる単語がそれぞれアラートに出されます。超ウザイ。(笑)

each, eachSlice, all, any, collect, detect, findAll, grep, include, inGroupsOf, inject, invoke, max, min, partition, pluck, reject, sortBy, toArray, zip, size, inspect, map, find, select, filter, member, entries, every, some, _reverse, _each, clear, first, last,compact, flatten, without, reverse, reduce, uniq, intersect, clone, toJSON


ん??「toArray」などという文字列が出ているあたり、なんかメソッド名っぽい。。。

疑いの矛先はprototype.jsを指しました。レッツ解剖っ(ソースコード見てみました。)


あらら、どうやらArrayを拡張しているらしいです。
「Array.prototype」がどうとかなんとか。

「いやぁ、さすがprototype.jsだわあ」と思った瞬間でした。(←?)



ところで、これらはメソッドであり、配列の要素じゃないからfor-inで出てるくのはおかしいんじゃねぇの??...と若僧は思ったのですが、
そういえばこんな記事を見たことがありました。

javascriptの関数が変態すぎる - 俺のメモ
URL:http://d.hatena.ne.jp/kayai/20110131

(こちらの記事の趣旨とはあまり関係ないですが印象に残っていたので引用させていただきます。)

そうでした。関数もオブジェクトとして変数に入れられたのでした。
つまりは関数の入った変数がプロパティになっていたわけで。(ですよね??^^;)


まったく...それは困ったな...for-in構文を使うなということか...。


ふつうにforで。。。

結局はforで素直にやりゃいいんですよね、forで。

// 配列変数の宣言
var ary = new Array( 10, 20, 30, 40, 50 );

// ふつうにforで。
for( i = 0; i < ary.length; i++ ){
    alert( i );
}


このforだと、さっきの見知らぬプロパティは出ません。


あれっ、プロパティになったくせに「配列名.length」には反映されてないのかよコンチクショウッ。
(ここはよくわかっていない...)

若僧の戯言なのでご容赦をば。。。ご指摘は大歓迎でございますっ。

結局この件で1時間ほどあがいていました(泣)
もうちょっと早く解決できるようになりたいです。精進せねば(--;;


[2011.03.11] 追記:配列はfor、連想配列はfor-in

...と、ここまで書いたのですが、すみません、勘違いしている部分がありました。

まずはこちらのサイト...
JavaScript の配列と連想配列の違い
URL:http://d.hatena.ne.jp/amachang/20070202/1170386546

普段からよくPHPを使っているのですが、そこでは配列も連想配列も見境なしにforeach構文を使っていました。(もしかしてそれもダメだったりするのでしょうか。。。)

// 連想配列の宣言
var ary = { hoge : "hogeVal", foo : "fooVal" };

// 連想配列にはfor-in
for( i in ary ){
    alert( i );
}

おぉ、確かに先程のような打ち覚えのない単語は出てきません!!

つまり、配列はfor構文、連想配列はfor-in構文を使うということですね。


失礼いたしましたm(_ _;)m

他参考:『Array.prototype は使用しない方がいい? - JavaScript - 教えて!goo
URL:http://oshiete.goo.ne.jp/qa/5081024.html
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

テーマ : JavaScript /  ジャンル : コンピュータ

コメントの投稿

非公開コメント

カテゴリー
ようこそ!
Author: Torasuke
Profile: 地元大学の情報系学部に息をひそめる二回生。
   SA SW


ブログ内検索
最近のコメント
オススメ
京都の大学生のラボブログ
Python,Java,Objective-C,GAE,Macなど
Python独習中の大学生のブログ


ltzz.info
ここの管理者さんには謁見済み!(えっ

 Use OpenOffice.org
無補償でも良いなら、MSOfficeよりOpenOfficeで十分です。

Mozilla Firefox ブラウザ無料ダウンロード
当サイトは、Firefoxというブラウザで動作確認しています。私は以前、IE派でしたが、一度乗り換えて慣れてしまうと、Firefoxのほうが便利だということを実感しました。

是非よろしくお願いします。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。