0

このように、プロトタイプを使用して配列をサブクラス化しています。

MyArray = function()
{
   Array.apply(this, arguments);
};

MyArray.prototype = new Array();

すべてが期待どおりに正常に機能し、次の方法で「MyArray」インスタンスを初期化できます。

var arr = new MyArray();
arr.push(1, 2, 3);

問題は、MyArrayインスタンスの高速列挙が壊れていることです。実際には、次のループがあります。

for (var i in arr)
{
   console.log(i);
}

プリント:0、1、2、長さ

実際には、クラスのすべてのメソッド/プロパティが列挙に含まれています。通常の配列では、コードは0、1、2のみを出力します(これらの数値は配列のインデックスです)。

だから...私の質問は:高速列挙を維持することによって配列を拡張するにはどうすればよいですか?

ps:Objective Cでは、高速列挙を実装するためにメソッドをオーバーライドする必要があります... JavaScriptでオーバーライドする特別なメソッドはありますか?

注:明らかに、「MyArray」の実際の実装は少し異なりますが、投稿したコードは、異常な高速列挙ループを生成するのに十分です。なぜ私が配列を拡張しているのか私に聞かないでください、私には正当な理由があります;)

4

1 に答える 1

3

配列要素は、オブジェクトの列挙可能なプロパティを反復するため、決して列挙しfor (var x in obj)ないでください。配列要素だけでなく、配列要素以外のものも含めることができます。さらに、この反復方法では、プロパティが特定の順序で返されるとは限らないため、配列要素が正しい順序になっていない可能性があります。

最新のブラウザでは、Object.defineProperties()メソッドを使用してプロパティを作成し、プロパティを列挙可能かどうかを指定できますが、それでも、配列の要素を。で列挙することが正しいとは限りませんfor (var x in obj)。配列要素を反復するために、常にこのタイプのフォームを使用する必要があります:for (var i = 0, len = arr.length; i < len; i++)またはのような組み込みのイテレータarray.forEach(callback [, thisArg])

于 2012-09-03T16:49:42.917 に答える