- 締切済み
prototype.jsを使うとfor~inがバグる件
下記について知っている人が居ましたら教えてください。 HTAでprototype.jsを使うとfor~inでバグります。 具体的に, prototype.jsを読み込んだ状態でfor~inして, for~inの情報を参照すると,値ではなくソースコードが表示されます。 prototype.jsを読み込ませない場合で,通常のようにfor~inして, for~inの情報を参照すると,問題なく値が参照できます。 OS環境とバージョンによって違うかもしれませんが,僕の環境では現象が発生します。 対策方法を知っている人がいましたら教えてください。 下記のソースを実行すると, バグらない場合は,次のように出力されます。 hoge piyo toge バグる場合は,次のように出力されます。 function(item, i) { i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; var n = this.slice(0, i).reverse().indexOf(item); return (n < 0) ? n : i - n - 1; } -略- { this._each(function(value) { iterator(value, index++); }); } catch (e) { if (e != $break) throw e; } return this; } hoge piyo toge prototype.js使用すると... ///////////////////////////////////// // sample.hta バグ <html> <head> <title>ツール</title> <script type="text/javascript" src="./prototype.js"></script> </head> <body onLoad="javascript:window.resizeTo(600,480)"> <script language="javascript"> { // Iniイメージ // [TEST] // KEY1=hoge // KEY2=piyo // KEY3=toge var section = "TEST"; var key = new Array("KYE1", "KYE2", "KYE3"); var data = new Array("hoge", "piyo", "toge"); // セクション items = new Array(); items[ section ] = new Array(); // キー for(var i=0;i<key.length;i++){ items[ section ][ key[i] ] = data[i]; } // 参照 for(var j in items[ section ]){ document.write( items[ section ][ j ] + "<br />\n" ); } delete key; delete data; delete items; } </script> </body> </html> prototype.js使用しないと... ///////////////////////////////////// // sample.hta バグらない <html> <head> <title>ツール</title> <!-- <script type="text/javascript" src="./prototype.js"></script> --> </head> <body onLoad="javascript:window.resizeTo(600,480)"> <script language="javascript"> { // Iniイメージ // [TEST] // KEY1=hoge // KEY2=piyo // KEY3=toge var section = "TEST"; var key = new Array("KYE1", "KYE2", "KYE3"); var data = new Array("hoge", "piyo", "toge"); // セクション items = new Array(); items[ section ] = new Array(); // キー for(var i=0;i<key.length;i++){ items[ section ][ key[i] ] = data[i]; } // 参照 for(var j in items[ section ]){ document.write( items[ section ][ j ] + "<br />\n" ); } delete key; delete data; delete items; } </script> </body> </html> prototype.jsを最後に読み込ませると... ///////////////////////////////////// // sample.hta バグらない <html> <head> <title>ツール</title> </head> <body onLoad="javascript:window.resizeTo(600,480)"> <script language="javascript"> { // Iniイメージ // [TEST] // KEY1=hoge // KEY2=piyo // KEY3=toge var section = "TEST"; var key = new Array("KYE1", "KYE2", "KYE3"); var data = new Array("hoge", "piyo", "toge"); // セクション items = new Array(); items[ section ] = new Array(); // キー for(var i=0;i<key.length;i++){ items[ section ][ key[i] ] = data[i]; } // 参照 for(var j in items[ section ]){ document.write( items[ section ][ j ] + "<br />\n" ); } delete key; delete data; delete items; } </script> <script type="text/javascript" src="./prototype.js"></script> </body> </html>
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- JidousyaGaisya
- ベストアンサー率23% (45/189)
RAMディスク化用のAPPとか常駐Software・Serviceとかによる邪魔の不在証明は、 果たして可能なのでしょうか?
- 小林 K太郎(@kingfruits)
- ベストアンサー率28% (2/7)
- yuu_x
- ベストアンサー率52% (106/202)
そもそも javascript に連想配列なるものは存在しません。 それから、もともと for in での配列ループは推奨されていないので、配列をループさせたい場合は地道にインデックスで。 配列でなく、オブジェクトを使用すると連想配列のような事も可能です。 var items = {}; item[ 'KEY1' ] = 'hoge'; 又は、 var items = { KEY1 : 'hoge', KEY2 : 'piyo', ... } delete items[ 'KEY1' ]; // items オブジェクトから KEY1 プロパティ削除 for( var key in items ) { document.write( 'key = ' + key + '<br>' ); document.write( 'value = ' + items[ ket ] + '<br>' ); }
- KI401
- ベストアンサー率53% (44/82)
色々と突っ込み所満載だから全部挙げていくが、まずは本題から。 * Array汚染 全ての原因はprototype.jsがArrayオブジェクトを汚染していることと、 そのArrayコンストラクタを使ってitemやitemsを作っていることだ。 そもそも、この場合のitemやitemsの用途は「ハッシュ(オブジェクト)」であって、配列「ではない」。 だから、初期化式はArrayコンストラクタなど用いず、"var item = {};"と、 ハッシュ(オブジェクト)として初期化すべきだ。 ※以下本題関係なし * language="javascript" <script language="javascript">は「古い記法」だ。 <script type="text/javascript">が推奨される。 * コメントアウト <script>要素内はコメントアウトすべきだ。ブラウザが誤解釈したら困る。 (今時そんなブラウザは皆無だが。) <script type="text/javascript"> //<!-- //--> </script> * コードブロック{ } javascriptにコードブロックの概念はない。よって、スクリプト全体を{}で囲っているが、 全く無意味だ。例えば次のように確かめられる: {var testvar = 1;} alert(testvar); // -> 1 ... NOT local variable!! 同じ理由で、for文の初期化式でindex用の変数i,jを宣言するのは好ましくない。次のように書くべき: var i; for (i=0; i<n; i++) {} * new Hoge() そもそも、使わなくていいならnew演算子はあまり使わない方がいい。 "new Array()"の代わりに[]を、"new Object()"の代わりには{}を使えばいい。 * prototype.js そもそもそもそも、こんな汚染を引き起こしやがるprototypeなんて引っこんで(以下自重
お礼
細かいところまで,ご指摘ありがとうございます。 僕も調べたのですが, Array汚染がされているみたいですね。 別の処理方式で検討してみます。 <script type="text/javascript"> //<!-- { Array.prototype.hogehoge = function() {}; // <-- 原因 Array.prototype.pagepage = function() {}; // <-- 原因 // Iniイメージ // [TEST] // KEY1=hoge // KEY2=piyo // KEY3=toge var section = "TEST"; var key = new Array("KYE1", "KYE2", "KYE3"); var data = new Array("hoge", "piyo", "toge"); // セクション items = new Array(); items[ section ] = new Array(); // キー for(var i=0;i<key.length;i++){ items[ section ][ key[i] ] = data[i]; } // 参照 for(var j in items[ section ]){ document.write( items[ section ][ j ] + "<br />\n" ); } delete key; delete data; delete items; } //--> </script> 結果: function() {} function() {} hoge piyo toge
お礼
本現象が発生する前に,上記のような連想配列を使用していました。 とても便利な処理方式ですが, 下記のようにArrayが拡張されたものが処理場に存在すると,for inしたときに値が不正になります。 Array.prototype.hogehoge = function() {}; Array.prototype.pagepage = function() {}; あまり納得がいきませんが, 別の処理方式で,意図的に連想配列を作り,メソッド化して地味に対応しました。