2016-11-11 24 views
13

Array.from(document.querySelectorAll('div'))または[...document.querySelectorAll('div')]を使用する場合、いくつかの違いがありますか?ここでArray.from()とスプレッドの構文

は一例です:

let spreadDivArray = [...document.querySelectorAll('div')]; 
console.log(spreadDivArray); 

let divArrayFrom = Array.from(document.querySelectorAll('div')); 
console.log(divArrayFrom); 

console.log()は同じ結果を記録します。

パフォーマンスの違いはありますか?

+0

スプレッド演算子で良いことは 'Object'をサポートしていることです。 performance .. idk –

+0

性能差があるかどうかを調べるには、ベンチマークを実行します。この結果は、ネイティブのES6環境にあるのか、ES5に移行しているのかによって大きく異なる可能性があります。 –

+6

主な違いは、 'Array.from'はイテレータプロトコル(すなわち' Symbol.iterator')を実装していない配列のようなオブジェクトで動作することです。 ES6や新しいブラウザ仕様でも、その数は少なくなります。 – nils

答えて

1

スプレッドは、配列がに展開され、になります。一方、from()新しい配列を作成します。 .from()は何にも展開されません。提供されたデータに基づいて新しい配列が作成されます。一方では、スプレッド演算子は新しいプロパティで配列を展開することができます。

+4

配列リテラルは常に新しい配列を作成します。 – Bergi

+2

私はあなたの言葉を誤解していますが、普及した演算子が新しい配列を作成する代わりに配列を変異させることを示唆していますか? – Bergi

+0

@Bergiよくスプレッド演算子は配列を作成しません。 OPの例での配列の作成は、スプレッド演算子を囲む角括弧で行います。 –

-1

Babelを使用すると、内部的に何が起こっているのかを確認するのに適しています。

ヘッドアップ。既定が間違っているので、Babelで最新のものが選択されていることを確認してください。

上記の例を使用すると、これが出力されます。

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } 

var spreadDivArray = [].concat(_toConsumableArray(document.querySelectorAll('div'))); 
console.log(spreadDivArray); 

var divArrayFrom = Array.from(document.querySelectorAll('div')); 
console.log(divArrayFrom); 
+2

'[] .concat'はノードリストがconcatspreadableでない場合には動作していませんか?それはバベルの成果ですか? – Bergi

+0

「それはバベルの出力ですか」確かに、コードをbabeljs.ioにコピーしました。例がありますか?必要なときにbabelが他の変換を行うかもしれません。これはもちろん、この特定のケースのテストだけです。 – Keith

+2

babeljs.io replには奇妙なオプションがありますが、それは本当に信頼できるものではありません。 '[]] .concat'を使うのは不正確な単純化です(配列の引数の広がり構文と同じです)。これはBabelのバグや未知の設定によって引き起こされる可能性があります。 – Bergi

5

さて、Array.from、すなわち、spread構文一方関数は配列リテラル構文の一部であり、静的メソッドです。あなたは、同じようなデータの周りに関数を渡すことができます。それらを1回、数回、または全く呼び出すことはできません。これは、この点に関して静的なspread構文では不可能です。

@nilsがすでに指摘しているもう1つの違いは、Array.fromも、反復可能なプロトコルを実装していない配列のようなオブジェクトで動作することです。一方、spreadにはiterablesが必要です。

+0

"Array.fromは配列のようなオブジェクトでも動作しますが、反復可能なプロトコルを実装していません" - そのようなオブジェクトの例を挙げることはできますか? – mpen

+0

Nevermind、[Michałは例を挙げました](https://stackoverflow.com/a/40549565/65387)。 – mpen

8

スプレッド要素it's not an operator)があるオブジェクトでのみ動作iterable(すなわち@@iteratorメソッドを実装)。 Array.from()は、配列のようなオブジェクト(すなわち、lengthプロパティとインデックスされた要素を持つオブジェクト)でも動作します。この例を参照してください:あなただけのアレイに何かを変換したい場合は

const arrayLikeObject = { 0: 'a', 1: 'b', length: 2 }; 
 

 
// This logs ['a', 'b'] 
 
console.log(Array.from(arrayLikeObject)); 
 
// This throws TypeError: arrayLikeObject[Symbol.iterator] is not a function 
 
console.log([...arrayLikeObject]);

また、私はそれはそれをより読みだからArray.from()を使用する方が良いと思います。スプレッド要素は、複数の配列(['a', 'b', ...someArray, ...someOtherArray])を連結する場合などに便利です。

+0

私は 'Array.from()'がこれを実装するために非常に読みやすい方法であることに同意しますが、私は普及している要素の構文 '... arrayLikeObject'も人々(またはそれ以上)にとって読みやすいと感じています。 – qarthandso

関連する問題