上記のコレクションのコンテンツを繰り返し処理して各項目を手動で配列にプッシュする以外に、HTMLCollectionを配列に変換するより効率的な方法はありますか?
Array.prototype.slice.call
を優先し、Brave(Chrome 59.0.3071に基づく)は、複数の実行にわたる2つのjavascriptテストに実質的な違いはありません。jsperf.com/htmlcollection-array-vs-jquery-childrenを
上記のコレクションのコンテンツを繰り返し処理して各項目を手動で配列にプッシュする以外に、HTMLCollectionを配列に変換するより効率的な方法はありますか?
Array.prototype.slice.call
を優先し、Brave(Chrome 59.0.3071に基づく)は、複数の実行にわたる2つのjavascriptテストに実質的な違いはありません。jsperf.com/htmlcollection-array-vs-jquery-childrenを
回答:
var arr = Array.prototype.slice.call( htmlCollection )
「ネイティブ」コードを使用しても同じ効果があります。
編集する
これは多くのビューを取得するため、(@ oriolのコメントに従って)次のより簡潔な式は実質的に同等であることに注意してください。
var arr = [].slice.call(htmlCollection);
しかし、@ JussiRのコメントに注意してください。「冗長」フォームとは異なり、プロセス内に空の、未使用の、実際には使用できない配列インスタンスが作成されます。コンパイラがこれについて行うことは、プログラマーのケンの外です。
編集する
ECMAScript 2015(ES 6)以降、Array.fromもあります:
var arr = Array.from(htmlCollection);
編集する
ECMAScript 2015は、機能的に同等のスプレッド演算子も提供しますArray.from
(ただしArray.from
、2番目の引数としてマッピング関数をサポートしています)。
var arr = [...htmlCollection];
上記の両方がで動作することを確認しましたNodeList
。
上記のメソッドのパフォーマンス比較:http : //jsben.ch/h2IFA
[].slice.call(htmlCollection)
も機能します。
Array.from
つまりfrom
、IE11ではサポートされていません。
これが最も効率的かどうかはわかりませんが、簡潔なES6構文は次のようになります。
let arry = [...htmlCollection]
編集:別のもの、Chris_Fコメントから:
let arry = Array.from(htmlCollection)
Array.from()
Array.from
つまりfrom
、IE11ではサポートされていません。
Array.prototype
同様に機能する、メソッドを取得するより簡潔な方法を見ました。HTMLCollection
オブジェクトをオブジェクトに変換する方法をArray
以下に示します。
[] .slice.call(yourHTMLCollectionObject);
そして、コメントで述べたように、IE7以前などの古いブラウザーでは、次のような互換機能を使用する必要があります。
function toArray(x) {
for(var i = 0, a = []; i < x.length; i++)
a.push(x[i]);
return a
}
私はこれが古い質問であることを知っていますが、受け入れられた答えは少し不完全だと感じました。だから私はこれをFWIWに捨てるつもりだと思った。
クロスブラウザーの実装については、prototype.js $A
関数をご覧になることをお勧めします
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
それは使用しませんArray.prototype.slice
、それはすべてのブラウザでは利用できませんので、おそらく。フォールバックが上のJavaScriptループであるため、パフォーマンスはかなり悪いと思いiterable
ます。
$A
関数がほとんどの場合に行っていることです。
これは、ここの情報(このスレッド)に基づく私の個人的な解決策です:
var Divs = new Array();
var Elemns = document.getElementsByClassName("divisao");
try {
Divs = Elemns.prototype.slice.call(Elemns);
} catch(e) {
Divs = $A(Elemns);
}
$ Aは、Gareth Davisの投稿で次のように説明されています。
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
ブラウザが最善の方法をサポートしている場合は、そうですが、そうでない場合は、クロスブラウザを使用します。
[,,]
なり[undefined, undefined]
ます。
これは、以前のIEバージョンを含むすべてのブラウザで機能します。
var arr = [];
[].push.apply(arr, htmlCollection);
jsperfはまだダウンしているので、さまざまなメソッドのパフォーマンスを比較するjsfiddleを次に示します。https://jsfiddle.net/qw9qf48j/
var args = (htmlCollection.length === 1 ? [htmlCollection[0]] : Array.apply(null, htmlCollection));
array-likeを効率的な方法で配列に変換するには、jQuery を利用できますmakeArray
。
makeArray:配列のようなオブジェクトを真のJavaScript配列に変換します。
使用法:
var domArray = jQuery.makeArray(htmlCollection);
少し余分:
配列オブジェクトへの参照を保持したくない場合(ほとんどの場合、HTMLCollectionsは動的に変更されるため、別の配列にコピーする方がよいです。この例では、パフォーマンスに細心の注意を払っています。
var domDataLength = domData.length //Better performance, no need to calculate every iteration the domArray length
var resultArray = new Array(domDataLength) // Since we know the length its improves the performance to declare the result array from the beginning.
for (var i = 0 ; i < domDataLength ; i++) {
resultArray[i] = domArray[i]; //Since we already declared the resultArray we can not make use of the more expensive push method.
}
配列のようなものは何ですか?
HTMLCollectionは"array-like"
オブジェクトであり、配列のようなオブジェクトは配列のオブジェクトに似ていますが、機能的な定義の多くがありません。
配列のようなオブジェクトは配列のように見えます。これらには、さまざまな番号付き要素と長さプロパティがあります。しかし、ここで類似性が停止します。配列のようなオブジェクトには配列の関数がなく、for-inループも機能しません。
for (var a=[], i=collection.length; i;) a[--i] = collection[i];
それほど「con」はありません:-)