20

ArrayJavaScriptとの違いObjectはそれほど大きくありません。実際、主にフィールドArrayを追加しているように見えるため、 sとsの両方を数値配列として使用できます。lengthArrayObject

var ar = new Array();
ar[0] = "foo";
ar["bar"] = "foo";

var ob = new Object();
ob[0] = "foo";
ob["bar"] = "foo";

assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.

だから私の質問は、人気のあるJavaScriptエンジンV8、JavaScriptCore、SpiderMonkeyなど)では、これはどのように処理されますか?明らかに、配列が実際にキー値を持つハッシュマップとして格納されることは望ましくありません。データが実際の配列として格納されていることを合理的に確認するにはどうすればよいですか?

私が見る限り、エンジンがとることができるいくつかのアプローチがあります:

  1. ArrayObject文字列キーを持つ連想配列として-とまったく同じ方法で実装されます。
  2. Arrayは特殊なケースでありstd::vector、数値キーを裏付ける-like配列と、必要に応じて異常なメモリ使用を防ぐための密度ヒューリスティックがあります。ar[100000000] = 0;
  3. Arrayはと同じObjectであり、すべてのオブジェクトは、配列を使用する方が理にかなっているかどうかを確認するためにヒューリスティックを取得します。
  4. 私が考えもしなかった、めちゃくちゃ複雑な何か。

適切な配列型( cough WebGL型の配列cough )があれば、これは実際にはもっと簡単です。

4

2 に答える 2

15

SpiderMonkeyでは、配列は基本的にjsvalsのC配列として実装されます。これらは「高密度アレイ」と呼ばれます。ただし、配列に似ていないこと(オブジェクトのように扱うなど)を開始すると、実装はオブジェクトに非常によく似たものに変更されます。

話の教訓:配列が必要な場合は、配列を使用します。オブジェクトが必要な場合は、オブジェクトを使用します。

ああ、jsvalは一種の可変個引数型であり、64ビットC型で可能なJavaScript値を表すことができます。

于 2012-02-18T02:42:24.220 に答える
7

V8およびCarakan(およびおそらくChakra)では、名前が配列インデックス(ES5で定義されている)であるプロパティを持つすべての(非ホスト)オブジェクト(配列であるオブジェクトとそうでないオブジェクトの両方)は、密な配列として格納されます(値ラッパーを含むC配列)またはスパース配列(バイナリ検索ツリーとして実装されます)。

統合されたオブジェクト表現は、列挙順序に影響を与えるという点でわかります。オブジェクトを使用すると、SpiderMonkeyとSquirrelFishの両方がすべてのプロパティを挿入順序で提供します。配列の場合、一般に(少なくとも、SMには特殊なケースがあります!)、最初に配列インデックスを作成し、次に他のすべてのプロパティを挿入順にインデックス付けします。V8、Carakan、およびChakraは、オブジェクトタイプに関係なく、常に最初に配列インデックスを指定し、次に他のすべてのプロパティを挿入順に指定します。

于 2012-07-11T13:31:38.933 に答える