下記について知っている人が居ましたら教えてください。
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>
A 回答 (4件)
- 最新から表示
- 回答順に表示
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>' );
}
本現象が発生する前に,上記のような連想配列を使用していました。
とても便利な処理方式ですが,
下記のようにArrayが拡張されたものが処理場に存在すると,for inしたときに値が不正になります。
Array.prototype.hogehoge = function() {};
Array.prototype.pagepage = function() {};
あまり納得がいきませんが,
別の処理方式で,意図的に連想配列を作り,メソッド化して地味に対応しました。
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なんて引っこんで(以下自重
細かいところまで,ご指摘ありがとうございます。
僕も調べたのですが,
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が見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- JavaScript GoogleChart 階層ごとのブロックの長さを個別に設定したい 1 2022/07/06 14:27
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- JavaScript 1日1回引けるJavaScriptおみくじについて 1 2022/12/12 22:28
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- JavaScript ①入力フォーム→②確認表示画面→③送信完了画面のコードを書いているのです、 入力フォームから受け取っ 2 2022/05/10 16:45
- JavaScript EasyUIのSubGrid(jquery)におけるObjectに入れた連想配列について 1 2022/05/02 11:21
- JavaScript 以前の質問だと、どの条件でも配列が表示されてしまいます。 1 2022/07/09 11:40
- AJAX JavascriptからPHPへのAjax通信でnullが返ってくる 3 2022/08/03 22:00
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/30 09:10
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C#OpenCv V4にのエラーに関する...
-
google apps scriptの終了のさせ方
-
ローカルにあるファイルを検索...
-
1日1回引けるJavaScriptおみく...
-
var_dumpのdump意味はを知りた...
-
gas スプレッドシートがアクテ...
-
翌月を取得するGASが分かりません
-
イベントが初めの一回しか起き...
-
どうすれば良いでしょうか?
-
HTMLにWSHを組み込む
-
C# 演算 奇数と偶数 表現の仕方
-
1日1回だけ引けるjavascriptお...
-
jqGridについて
-
Google Maps V3のズームの規制
-
javascriptでテーブルに追加し...
-
GASでundefinedエラーが出ます
-
ASP.NETのコントロールの値をJa...
-
C言語の質問です HTMLでこのよ...
-
なぜmatchメソッドがエラーにな...
-
指定日数経過でHTML上のデータ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
var exports = exports || {}; ...
-
google apps scriptの終了のさせ方
-
C#OpenCv V4にのエラーに関する...
-
GASでundefinedエラーが出ます
-
ジェネレーターの作り方
-
GASでGoogleフォームの自動返信...
-
HTMLで作った時報アプリが動き...
-
javascriptでテーブルに追加し...
-
html javascript リンク先アド...
-
【西暦等の変換】
-
ローカルにあるファイルを検索...
-
ASP.NETのコントロールの値をJa...
-
なぜmatchメソッドがエラーにな...
-
翌月を取得するGASが分かりません
-
gas スプレッドシートがアクテ...
-
ASP.NET MVCでObjectをjsに渡す
-
カンマで終わってるのはセミコ...
-
JavaScriptで文字列の特定文字...
-
javascriptでiframeのURL変更は?
-
APIを使って埋め込んだグーグル...
おすすめ情報