ループベースの手法を使用する必要があります。使用に基づくこのページの他の回答は.apply
、大規模な配列では失敗する可能性があります。
かなり簡潔なループベースの実装は次のとおりです。
Array.prototype.extend = function (other_array) {
/* You should include a test to check whether other_array really is an array */
other_array.forEach(function(v) {this.push(v)}, this);
}
その後、次のことができます。
var a = [1,2,3];
var b = [5,4,3];
a.extend(b);
DzinX の回答(push.apply を使用) およびその他の.apply
ベースのメソッドは、追加する配列が大きい場合に失敗します (テストでは、Chrome では約 150,000 エントリ、Firefox では 500,000 エントリを超えることが示されています)。この jsperfでこのエラーが発生していることがわかります。
第2引数に大きな配列を指定して「Function.prototype.apply」を呼び出すと、コールスタックサイズを超えるためエラーが発生します。(MDN には、 Function.prototype.applyを使用してコール スタック サイズを超える危険性に関する注意事項があります。「適用および組み込み関数」というタイトルのセクションを参照してください。)
このページの他の回答との速度比較については、この jsperfをチェックしてください(EaterOfCode に感謝します)。ループベースの実装は、 を使用した場合と同様の速度ですArray.push.apply
が、 よりも少し遅くなる傾向がありますArray.slice.apply
。
興味深いことに、追加する配列がスパースである場合、forEach
上記のベースド メソッドはスパース性を利用して、ベースド メソッドよりも優れたパフォーマンスを発揮し.apply
ます。これを自分でテストしたい場合は、この jsperfをチェックしてください。
ところで、(私がそうであったように!) forEach の実装を次のようにさらに短縮する誘惑に駆られないでください。
Array.prototype.extend = function (array) {
array.forEach(this.push, this);
}
これはガベージ結果を生成するためです。なんで?は、呼び出す関数に 3 つの引数を提供するためArray.prototype.forEach
、これらは (element_value、element_index、source_array) です。forEach
「forEach(this.push, this)」を使用すると、これらすべてが反復ごとに最初の配列にプッシュされます。