3

Internet Explorer で動作するように indexOf 実装を Array プロトタイプに取り込む方法については、多くの解決策がありますが、これまで見てきたどこにも対処されていないように見える問題に遭遇しました。

MDCでかなり合意された実装を使用すると、現在問題のある次のコードがあります。

// indexOf support for IE (from MDC)
if (!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(elt /*, from*/)   
    {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++)
        {
            if (from in this && this[from] === elt)  
                return from;
        }
        return -1;
    };
}

var i = [1,2,3,4];

for (j in i)
{
    alert(i[j]);
}

それぞれが配列の要素の 1 つを含む 4 つのアラートを受け取ることを期待しています。Firefox と Chrome ではまさにそのように表示されますが、IE8 では indexOf 関数コードを含む追加のアラートが表示されます。

これを避けるために何ができますか?

4

3 に答える 3

5

これは、IEではメソッドが存在しないため、メソッドがに追加され、Array.prototype列挙可能なままであるために発生します。

配列(および一般的には配列のようなオブジェクト)でのウォーキングには、このステートメントの使用はお勧めしません。for...in

なんで ?

  • このfor...inステートメントは、オブジェクトのプロパティを列挙することを目的としています。
  • for...inお気づきのように、ステートメントはプロトタイプチェーンをクロールします。
  • 反復の順序は任意である可能性があり、配列を反復すると、数値の順序で要素にアクセスできない場合があります。

最も単純なアプローチであるプレーンforループ:

for (var j = 0; j < i.length; j++) {
    alert(i[j]);
}

参照:

于 2010-05-19T19:37:30.057 に答える
3

これは、Array.prototypeを編集するため、作成された配列はすべてindexOf、「in」コマンドが表示できるカスタムメイドのVISIBLEメソッドを継承するためです。

for..inJavaScriptの構文は、たとえばPHPのforeachのようには機能しません。配列内のすべての項目を繰り返すだけでなく、配列OBJECTが持つ可能性のあるすべてのメソッドとプロパティを繰り返します(JavaScriptの配列は実際には「偽装」オブジェクトです)。ネイティブメソッドはfor..in構成には表示されませんが、すべてのカスタム追加は表示されません。

あなたの例では、どの配列も次のようになります。

Array:
- [0] value
- [1] value
- [2] value
- ..
- [N] value
- [IndexOf] value

不要な継承されたメソッドとプロパティを回避するには、次のメソッドを使用できますhasOwnProperty()

for (j in j){
    if(i.hasOwnProperty(j){
        alert(i[j])
    }
}

hasOwnPropertyキーが継承されておらず、実際のオブジェクトに属しているかどうかを確認します。このようにして、必要な値のみが通過します。

于 2010-05-19T19:34:12.783 に答える
0

追加してみてください:

for (j in i) {
    if (i.hasOwnProperty(j)) { 
        alert(j); 
    }
}
于 2010-05-19T19:28:38.207 に答える