HTMLCollectionを配列に変換するより効率的な方法はありますか?それは、コレクションの内容を繰り返し処理し、各アイテムを手動で配列にプッシュする以外にありますか?
9 に答える
var arr = Array.prototype.slice.call( htmlCollection )
「ネイティブ」コードを使用しても同じ効果があります。
編集
これは多くの見解を得るので、(@ oriolのコメントによると)次のより簡潔な表現は事実上同等であることに注意してください。
var arr = [].slice.call(htmlCollection);
ただし、@ JussiRのコメントによると、「verbose」形式とは異なり、プロセス内に空の未使用の実際には使用できない配列インスタンスが作成されることに注意してください。これについてコンパイラーが行うことは、プログラマーの知識の範囲外です。
編集
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
これが最も効率的かどうかはわかりませんが、簡潔な ES6 構文は次のようになります。
let arry = [...htmlCollection]
編集:Chris_Fコメントからの別のもの:
let arry = Array.from(htmlCollection)
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
おそらく、すべてのブラウザで利用できるわけではないため、使用しません。フォールバックがiterable
.
これは、以前の IE バージョンを含むすべてのブラウザーで機能します。
var arr = [];
[].push.apply(arr, htmlCollection);
jsperf は現時点ではまだダウンしているため、さまざまなメソッドのパフォーマンスを比較する jsfiddle を次に示します。https://jsfiddle.net/qw9qf48j/
効率的な方法で配列のような配列を配列に変換するには、jQuery makeArray
を利用できます。
makeArray: 配列のようなオブジェクトを真の JavaScript 配列に変換します。
使用法:
var domArray = jQuery.makeArray(htmlCollection);
少し余分:
配列オブジェクトへの参照を保持したくない場合 (ほとんどの場合、HTMLCollection は動的に変更されるため、別の配列にコピーすることをお勧めします。この例では、パフォーマンスに細心の注意を払っています。
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 ループも機能しません!
これは、ここの情報に基づいた私の個人的な解決策です(このスレッド):
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;
}
ブラウザが最適な方法をサポートしている場合は OK、それ以外の場合はクロス ブラウザを使用します。