疑似配列(配列のようなオブジェクトまたはコレクション)について少し。 「それは何ですか?」、「彼らと一緒に仕事をする方法は?」など

この記事では、擬似アレイについて説明します:「これは何ですか?」、「それらをどのように使用するか?」、「それらは配列とどう違うのですか?」、「それらを配列に変換する方法は?」

また、開始する前に、この情報がJavaScriptにのみ適用されることを明確にします。 つまり、JavaScript言語の擬似配列について説明します。

擬似配列(配列のようなオブジェクトまたはコレクション)とは何ですか?


擬似配列は、構造的に配列に類似したオブジェクトです。 つまり、数値プロパティ(インデックス)とlengthプロパティがあります。

例:
 {0: ' 1', 1: ' 2', 2: ' 3', length: 3}; 

擬似配列は配列とどう違うのですか?


擬似配列と配列の主な違いは、プロトタイプの継承、つまり__proto__プロパティです。

配列のプロパティを見ると、 Arrayオブジェクトのプロトタイプを継承していることがわかります。 つまり、 Array.prototypeオブジェクトにあるすべてのプロパティは、どの配列でも使用できます。 擬似配列のプロパティを見ると、他のプロパティとともに他のオブジェクトのプロトタイプを継承していることがわかります。

擬似配列に関連するオブジェクトタイプのリスト


擬似配列は、さまざまなオブジェクトのプロトタイプを継承できます。 オブジェクトタイプの小さなリスト-疑似配列を次に示します。


これは、50を超えるタイプを持つ疑似配列タイプの完全なリストのごく一部です。 記事の次の段落はこれから続きます。

通常のオブジェクトと擬似配列を区別する方法は?


3日間、さまざまな記事を読みながらこの質問を整理しました。その結果、条件を1つだけ作成しました。オブジェクトが擬似配列の場合、 lengthプロパティが必要です。これは整数で、ゼロ以上でなければなりません。

 Number.isInteger(Number(object.length)) && Number(object.length) >= 0 

次のアイテムを折りたたんでこの状態を作りました。

  1. 数値のプロパティと等しくすることはできません。それらを指定しない場合、これらが等しくないことを意味しないためです。 それらは単にundefinedと等しくなります
  2. 擬似配列のタイプを見ると、それらのタイプにCollectionMapまたはListという単語が含まれていることがわかりました。 しかし、疑似配列は通常のオブジェクトのタイプを持つことができるため、この考えはすぐに解消されました-Object、
    そして、普通の配列でさえこの項目に該当しないため、一般にこれは愚かです。
  3. 非数値プロパティを配列に含めることができるため、非数値プロパティを同等にすることもできません。

しかし、JavaScriptは私の状態が酷すぎると「言った」。 疑似配列を配列に変換するためのオプションを分析すると、JavaScriptは、 lengthプロパティがゼロ以上の数値に等しい疑似配列を「食べる」ことに気付きました。

 typeof object.length === 'number' && Number(object.length) >= 0 

また、数値が整数である必要はありません(場合を除く)。 JavaScriptは、小数を指定された値以下の最大の整数に変換します。

例:
 Array.from({0: ' 1', 1: ' 2', length: 1.6}); // [' 1'] Array.from({0: ' 1', 1: ' 2', 2: ' 3', length: 2.3}); // [' 1', ' 2'] 

擬似配列を配列に変換する方法は?


擬似配列を配列に変換するには、いくつかのオプションがあります。

  1. 擬似配列値を通常の配列に列挙します
    初心者の頭に浮かぶ最初のオプションは、疑似配列から配列にすべての値をループすることです。

     var object = {0: 1, 1: 2, 2: 3, length: 3} var array = []; //     for (var i = 0; i < object.length; i++) { array.push(object[i]); }; console.log( array ); // [1, 2, 3] 

  2. Array.from()関数を使用する
    ブラウザーが異なるサイトでこの機能をサポートするテーブルが異なるため、このオプションは少し議論の余地があります。 しかし、私は自信を持って、すべての最新のブラウザーでこの方法が機能すると言うことができます。

     var object = {0: 1, 1: 2, 2: 3, length: 3} //     var array = Array.from(object); console.log( array ); // [1, 2, 3] 

  3. Array.prototype.slice.call()[].slice.call() )関数を使用する
    これは「私たちの祖父と祖母」の方法であり、現在も機能しています。

     var object = {0: 1, 1: 2, 2: 3, length: 3} //     var array = Array.prototype.slice.call(object); //   : [].slice.call(object); console.log( array ); // [1, 2, 3] 

  4. スプレッド演算子を使用する
    この記事を書いている時点でのこの方法は、まだすべてのブラウザでサポートされているわけではなく、「ルート」擬似NodeListNodeListHTMLCollectionなど)でのみ機能するため、かなり議論の余地があります。

     var object = document.querySelectorAll(selector); //     var array = [...object]; console.log( array ); // [element, element, element] 

  5. __proto__プロパティを変更することにより
    このプロパティについては、記事の冒頭で説明しました。 オブジェクトのArray.prototypeプロパティをArray.prototypeに変更すると、擬似配列は配列に変換されます。 しかし、このメソッドは、私が書いた「いくつかの場合を除き」に含まれています。なぜなら、配列への完全な変換のためには、 lengthプロパティは整数でなければならないからです。

     var object = {0: 'a', 1: 'b', 2: 'c', length: 3} //  __proto__  object.__proto__ = Array.prototype; console.log(object); // ['a', 'b', 'c'] 

    また、ここには1つの機能があります。 length擬似配列のレコード数よりも少ない数に指定すると、 lengthで指定されたレコード数と残りのレコードから追加のプロパティを持つ配列を取得します。

     var object = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', length: 3} //  __proto__  object.__proto__ = Array.prototype; console.log(object); // ['a', 'b', 'c', 3: 'd', 4: 'e'] 

    そしてもう1つ注意してください:このメソッドは、オブジェクトを実際の配列にしませんが、必要なパラメーターを与えます。 これを確認するには、 Array.isArray();関数を使用してオブジェクトをチェックしますArray.isArray();

     var object = {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', length: 3} //  __proto__  object.__proto__ = Array.prototype; console.log( Array.isArray(object) ); // false 


これらは最も一般的な変換方法です。 また、たとえば、 forEachを使用して擬似forEachを反復処理したり、 filter関数でフィルター処理したりする必要がある場合は、これらすべてのメソッドを省略できることも言う必要があります。 このような目的のために、関数には追加の関数.call()があります。これにより、擬似配列を操作できます。

例:
 var object = {0: 'a', 1: 'b', 2: 'c', length: 3} //      object = Array.prototype.map.call(object, v => ': ' + v); //  : [].map.call(object, v => ': ' + v) console.log(object); // [': a', ': b', ': c'] 

これで、この記事を終了します。 彼は私に彼が何を望んだか、そしてそれがあなたにとって役に立つかどうかはあなた次第だと言った。

Source: https://habr.com/ru/post/J336136/


All Articles