Javascript技術のはfor in文で配列を巡回しないでください.
1630 ワード
なぜfor in文を使わないですか?
jqModalというjqueryプラグインは多くの人が使ったことがあると思います.jqModalのソースコードの内部には、hsという関数があります.
2番目のfor inは、コンテキストによってthis[i]が配列オブジェクトであることを確認します.
多くのJS先駆者は、行列の対象に対してfor in文を使って遍歴しないようにと警告しています.その原因は性能以外に、予想外のバグを生む可能性があります.先人の話を聞かないと損をするよ.
今日はjqModalを例にとって、このようなバグがいつ出現するかを説明します.
二、問題再現キーワード:原生Aray類、拡張Aray類
for in文で配列オブジェクトを巡回する潜在的なバグは、元のAray類が他のjsスクリプトライブラリにプロトタイプ拡張されている場合(例えば、toJSON方法であるAray.prototype.toJSON=xxx)、for inで巡回して拡張されたArayオブジェクトの論理と遍歴元Arayオブジェクトの論理とは異なる.
簡単な例をあげます.
もしあなたが設計したコードのロジックが元のAray類を基準にしていたら、ある日あなたの同僚がページの中で第三者のJSライブラリを引用しました.このライブラリはまたAray類を拡張しました.結果は想像しにくいです.元のコードロジックはもう成立しないかもしれません.
この種の拡張元JS類のライブラリについて、有名なのはプロトタイプ.jsです.それはAray類にたくさんの方法を広げました.例えばtoJSON、eachなどです.なぜjqueryの創始者はプロトタイプに火をつけましたか?(多くの人が特殊な原因で一つのページでjqueryを同時にprototypeを使っています.予想外の衝突問題がたくさんあります.一つのnoConflicktだけでは解決できません.)また、jqmodalの作者が私のこの文章を読めばprototypeに対して不満を言うかもしれません.
以上のように、jqmodalを使っていたら、他の理由でprototypeを使っていて、おめでとうございます.衝突によってjqModalのフレームがie 6、ie 7の下にあると、close Classで設定されたボタンで自動的に閉じることができなくなります.追跡デバッグコードが発見されます.異常なところは本稿の冒頭で述べたhs方法のforサイクルにあります.
三、問題を解決して配列のところを遍歴して、for var文でfor inに代えます.
jqModalというjqueryプラグインは多くの人が使ったことがあると思います.jqModalのソースコードの内部には、hsという関数があります.
for(var i in {jqmShow:1,jqmHide:1})
for(var s in this[i])
if(H[this[i][s]])
H[this[i][s]].w[i](this);
return F;
}
最初のfor in巡回のターゲットは匿名のオブジェクトです.大丈夫です.2番目のfor inは、コンテキストによってthis[i]が配列オブジェクトであることを確認します.
多くのJS先駆者は、行列の対象に対してfor in文を使って遍歴しないようにと警告しています.その原因は性能以外に、予想外のバグを生む可能性があります.先人の話を聞かないと損をするよ.
今日はjqModalを例にとって、このようなバグがいつ出現するかを説明します.
二、問題再現キーワード:原生Aray類、拡張Aray類
for in文で配列オブジェクトを巡回する潜在的なバグは、元のAray類が他のjsスクリプトライブラリにプロトタイプ拡張されている場合(例えば、toJSON方法であるAray.prototype.toJSON=xxx)、for inで巡回して拡張されたArayオブジェクトの論理と遍歴元Arayオブジェクトの論理とは異なる.
簡単な例をあげます.
var x=[1];
for(var s in x){
alert(s);
};
一般的には、Arayが元のjsクラスであれば、上記の文は一回のalert方法だけを実行し、sは配列のインデックス0であるべきです.しかし、Aray類が拡張されて一つのtoJSON方法が増えたら、上の文は二回のalertを実行し、第一回のsはインデックス0、第二回のsは方法名'toJSON'です.もしあなたが設計したコードのロジックが元のAray類を基準にしていたら、ある日あなたの同僚がページの中で第三者のJSライブラリを引用しました.このライブラリはまたAray類を拡張しました.結果は想像しにくいです.元のコードロジックはもう成立しないかもしれません.
この種の拡張元JS類のライブラリについて、有名なのはプロトタイプ.jsです.それはAray類にたくさんの方法を広げました.例えばtoJSON、eachなどです.なぜjqueryの創始者はプロトタイプに火をつけましたか?(多くの人が特殊な原因で一つのページでjqueryを同時にprototypeを使っています.予想外の衝突問題がたくさんあります.一つのnoConflicktだけでは解決できません.)また、jqmodalの作者が私のこの文章を読めばprototypeに対して不満を言うかもしれません.
以上のように、jqmodalを使っていたら、他の理由でprototypeを使っていて、おめでとうございます.衝突によってjqModalのフレームがie 6、ie 7の下にあると、close Classで設定されたボタンで自動的に閉じることができなくなります.追跡デバッグコードが発見されます.異常なところは本稿の冒頭で述べたhs方法のforサイクルにあります.
三、問題を解決して配列のところを遍歴して、for var文でfor inに代えます.