• 締切済み

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>

みんなの回答

回答No.4

RAMディスク化用のAPPとか常駐Software・Serviceとかによる邪魔の不在証明は、 果たして可能なのでしょうか?

回答No.3
  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.2

そもそも 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>' ); }

C_se0430
質問者

お礼

本現象が発生する前に,上記のような連想配列を使用していました。 とても便利な処理方式ですが, 下記のようにArrayが拡張されたものが処理場に存在すると,for inしたときに値が不正になります。 Array.prototype.hogehoge = function() {}; Array.prototype.pagepage = function() {}; あまり納得がいきませんが, 別の処理方式で,意図的に連想配列を作り,メソッド化して地味に対応しました。

  • KI401
  • ベストアンサー率53% (44/82)
回答No.1

色々と突っ込み所満載だから全部挙げていくが、まずは本題から。 * 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なんて引っこんで(以下自重

C_se0430
質問者

お礼

細かいところまで,ご指摘ありがとうございます。 僕も調べたのですが, 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

関連するQ&A