web-dev-qa-db-ja.com

スプレッド構文vsスライス法

私は、次のアプローチでスプレッド構文とスライス方法の違いを理解しようとしていました。

配列の実際のコピーを作成したい場合、スプレッド構文を使用して簡単に実行できます

var fruits = ["Banana", "Chips" , "Orange", "Lemon", "Apple", "Mango"]
var newCitrus = [...fruits]

Console.logこれを

["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"] 

しかし、sliceメソッドを使用して配列のコピーを作成することもできます。上記と同じ配列を考えて、このようなことをしたら...

var citrus = fruits.slice(0);

コンソールにログを記録すると、スプレッド構文で取得したのとまったく同じ配列が得られます

["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"] 

両方ともコード/書き込みにほぼ同じ時間がかかるため、ここでの違いは何ですか?通常、どのアプローチを選択する必要がありますか?

14
iRohitBhatia

sliceを除くパフォーマンスはArray.prototypeの単なる関数であるため、配列に対してのみ機能します。一方、Spread構文は反復可能( 反復可能プロトコル を満たすオブジェクト)で機能するため、StringArrayTypedArrayMap、およびSetでそのまま使用できます。また、簡単に カスタムイテラブルを作成 にすることもできます。

穴のあるsliceing配列とspreading配列(スパース配列)に関しても違いがあります。以下に示すように、sliceはスパース性を保持しますが、spreadは穴をundefinedで埋めます。

Array(3)         // produces sparse array: [empty × 3]
Array(3).slice() // produces [empty × 3]
[...Array(3)]    // produces [undefined, undefined, undefined]

Spread構文を使用して、オブジェクトの浅いクローンを作成することもできます。

const obj = { foo: 'bar', baz: 42 };
const clone = { ...obj1 };
obj.foo === clone.foo // true
obj.baz === clone.baz // true
obj === clone         // false (references are different)
10

Chromeで測定 は、1秒あたり4Mの操作に対して1秒あたり67Mの操作で、スプレッドオペレーターよりもはるかにパフォーマンスが高いことを示します。 ChromeまたはChromiumを使用するElectronアプリ)を構築する場合は、特にビッグデータとリアルタイムアプリケーションの場合、スライスに行きます。

Measure results

編集:

Spread演算子は、Sliceよりもまだ遅いですが、はるかに高速になっているようです。

Newer Measurement Results

5

Chrome(72+)の新しいバージョンは、パフォーマンスのギャップを解消したようです。 https://measurethat.net/Benchmarks/ListResults/2667

3
pixelbandito

ただし、これら2つの方法は実際には同等ではありません。スライスは_Array.prototype_の関数であり、配列の実装を認識しています。これにより、非常に効率的なディープコピーが作成されます。さらに重要なことですが、.slice()は配列の疎情報を保持します。

対照的に、_[...Array]_は、既存の配列の反復可能なビューから新しい配列を作成するだけです。必ずしも効率的ではありません。

これを試して:

_var a = [];
a.length = 3;
console.log("slice:", a.slice());
console.log("spread:", [...a]);
_

Chromeブラウザ開発者コンソールでは、次の結果が得られます。

_slice: (3) [empty × 3]
spread: (3) [undefined, undefined, undefined]
_

配列が特に巨大+スパースの場合、array.slice()は非常に高速です。 _[...array]_はおそらくブラウザをハングさせます。

3
monarch_dodra

パフォーマンスは、実行されているエンジンによって異なります。そして、ほとんどのJavscriptコードと同様に、おそらくさまざまなエンジンで実行されます。したがって、見た目が良いものを使用してください。私にはそれが広がっています。

_..._は純粋な美しさです。

スライスを使用する場合は、0をスキップして、.slice()とだけ言ってください。

2
rmn