0

Array indexOf のプロトタイプを定義しました (Internet Explorer で array indexOf をサポートするため)。

if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
               return i;
            }
         }
         return -1;
     }
}

値 [1,2,3] の配列を作成すると、この indexOf コード スニペットが以下のように配列に追加されます

["1","2","3",function(obj){for(var i=0;i<this.length;i++){if(this[i]==obj){return i;}}return -1;}]

この問題は IE でのみ発生します。

誰でもこの問題を解決するのを手伝ってくれますか? 前もって感謝します。


ループはどこにも使用しませんでした。for...inこのため、jQuery sortable toArray method を使用して い.sortable("toArray");ます。

4

3 に答える 3

1

ある時点で、for...inループを使用して配列の要素を反復処理していると想定しています。例えば:

for (var elem in myArray) {
    //Do stuff...
}

ループは、オブジェクトのすべてのfor...in列挙可能なプロパティを列挙します。これには、プロトタイプ チェーンの祖先から継承したものも含まれます。Arrayプロトタイプにメソッドを追加しました:

Array.prototype.indexOf = function(obj){ //...

このプロパティは列挙可能です (列挙不可能なプロパティを定義することはできませんObject.defineProperty。古いバージョンの IE を参照してください)。したがって、for...inループにはこのプロパティが含まれます。

簡単な解決策は、ループを使用して配列を反復処理しないことfor...inです。代わりに通常のforループを使用してください。

于 2012-09-19T13:50:59.730 に答える
0

問題は、新しいindexOf()メソッドが「列挙可能」とマークされていることです。残念ながら、IE7 または非標準モードの IE8 では、これに対する修正はありません。ただし、ES5 のトリックを使用することで、少なくとも標準モード IE8 の問題にパッチを当てることができます。コードを次のように変更すると、IE8 標準モードの場合は余分な要素が削除されます。

(function () {
    var indexOfFn = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
               return i;
            }
         }
         return -1;
    };

    if(!Array.prototype.indexOf){
        if(typeof Object.defineProperty === "function") {
            Object.defineProperty(Array.prototype, "indexOf", {
                value: indexOfFn,
                enumerable: false
            });
        } else {
            Array.prototype.indexOf = indexOfFn;
        }
    }
}());

私はそれが冗長であることを知っているので、努力する価値がないかもしれません. しかし、それはまた、あなたの JavaScript を、for-in ループで配列を使用することになるかもしれない他の人々の悪いコーディングからも保護します。

于 2012-09-19T13:49:21.593 に答える
0

それは非常に簡単です。配列には 4 つの要素が含まれており、そのうちの 4 番目は関数オブジェクトです。すべての配列オブジェクトは言うまでもなく、配列オブジェクトの新しいメソッドを定義していません。スクリプトの一番上に最初のスニペットを貼り付けるだけで、次のようになります。

 var foo = [1,2,3];
 alert(foo.indexOf(2));//alerts 1

Array.prototypeすべての配列のテンプレートと考えてください。エラーをスローするのではなく、定義されていない配列のプロパティまたはメソッドにアクセスしようとすると、JSは最初にArray.prototypeそのオブジェクトにそのメソッド/プロパティがないかどうかを確認します。存在する場合、JS はそのコードを使用し、最初に呼び出した配列に適用します。上記の例では、 のようfoo.indexOf(2)に記述できますArray.prototype.indexOf.apply(foo,[2]);。つまり、JS は自動的にプロトタイプの機能を に適用しましたfoo

「完全な」コードは次のようになります。

if(!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(obj)
    {
        for(var i=0; i<this.length; i++)
        {
            if(this[i] === obj)//preferable, use strict comparison
            {
                return i;
            }
        }
        return -1;
    };
}
var yourArray = [1,2,3,4,'4'];
alert(yourArray.indexOf(4));//alerts 3
alert(yourArray.indexOf('4'));//alerts 4 when using strict comparison, if not, alerts 3

ここにフィドルがあり、IE8でチェックされ、問題なく動作しています

プロトタイプの継承プロトタイプ チェーンをググるか、JS などでプロトタイプを拡張するだけで、よく読んで困惑してください。;)

于 2012-09-19T13:41:00.660 に答える