4

私の仕事

私のJavaScriptコードでは、オブジェクトを使用してキーを値に「マップ」しているので、後で特定の値を介して直接アクセスできます。例えば:

var helloMap = {};
helloMap.de = "Hallo";
helloMap["en"] = "Hello";
helloMap.es = "Hola";

そこで、2つの利用可能な表記オブジェクトスタイル配列スタイルを使用して、ソースコードでマップオブジェクトを段階的に構築します。

後でhelloMap["de"]、たとえば、追加した値にアクセスできます。したがって、オブジェクトに属性が設定されている順序を気にする必要がなければ、これで問題ありません。

オブジェクトのプロパティを今すぐ繰り返したい場合は、追加された順序でオブジェクトを繰り返すことを保証する方法はありません。

注:ラッパーオブジェクトを使用して、そこに配列を保持し、そのメソッドを使用して値を追加することはできません。次のようになります。

var HelloMap = function(){
  this.myMap = [];
  this.addProperty = function(key, value){
    this.myMap.push({key: key, value: value});
  }
}

または同様のものは私にはうまくいきません。したがって、ソリューションは、オブジェクトを使用するプログラマーに対して完全に透過的である必要があります。

つまり、必要なオブジェクトは、追加されたプロパティの順序を維持する空のオブジェクトになります。このようなことは次のようになります。

var helloMap = {};
helloMap = getOrderAwareObject(helloMap);

helloMap.xy = "foo"フォームのそれ以降のすべての割り当てがhelloMap["yz"] = "bar"オブジェクトで「順番に」追跡されるように、

可能な解決策

アンダースコアやjQueryでそのような特別なオブジェクトを提供するソリューションが見つからなかったため、JavaScriptオブジェクトのプロパティのゲッターとセッターを定義する可能性に出くわしました。ECMAScript5標準Object.defineProperty依存できるため、それを使用できます。

これの問題は、実際に設定する前に、オブジェクトに設定できるすべての可能なプロパティを知っている必要があることです。あなたがそれを定義するならば、あなたはそれに名前を付けなければならないので。

私が探しているのは、プロパティにゲッターとセッターが定義されていない場合にオブジェクトに適用されるデフォルトのゲッターデフォルトのセッターのようなものです。したがって、ソートされたマップをオブジェクトインターフェイスの背後に隠すことができます。

  • あなたが知っているフレームワークでこれに対する解決策はすでにありますか?
  • 「デフォルトのゲッター/セッター」のようなメカニズムはありますか?
4

5 に答える 5

6

内部で配列を使用する何らかのラッパーが必要になると思います。ECMAScript 5 (現在のブラウザー JavaScript 実装のベースとなっている標準) では、順序付けされたオブジェクト プロパティが許可されていません。

ただし、ECMAScript 6 には、順序付けられたプロパティを持つMap実装があります。http://www.nczonline.net/blog/2012/10/09/ecmascript-6-collections-part-2-maps/も参照してください。

ECMAScript 6 には他のオプションがある場合もあります。次の質問を参照してください。

ECMAScript 5 を使用してデフォルトのゲッターとセッターを定義するにはどうすればよいですか?

于 2013-02-01T11:38:51.660 に答える
5

このスレッドで今後参照できるように、並べ替えられたマップやその他の実装を提供するカスタム JavaScript ライブラリへのリンクを追加します。https://github.com/monmohan/dsjslib -msinghをチェックしてください

于 2013-08-27T06:00:41.180 に答える
3

一般的な解決策はわかりませんが、非一般的な解決策は非常に簡単に構築できます。

通常、配列のプロパティとして定義されたいくつかのメソッドを使用して、オブジェクトの配列を維持します。少なくとも、それが私のアプローチです。

これは、より大きなアプリケーションから(変更された形式で)取られた例です。

var srcs = [];
srcs.find = function(dist) {
    var i;
    for(i=0; i<this.length; i++) {
        if(dist <= this[i].dist) { return this[i]; }
    }
    return null;
};
srcs.add = function(dist, src) {
    this.push({ dist:dist, src:src });
}
srcs.remove = function(dist) {
    var i;
    for(i=0; i<this.length; i++) {
        if(this[i].dist === dist) {
            srcs.splice(i,1);
            return true;
        }
    }
    return false;
};
srcs.add(-1, 'item_0.gif' );
srcs.add(1.7, 'item_1.gif');
srcs.add(5, 'item_2.gif');
srcs.add(15, 'item_3.gif');
srcs.add(90, 'item_4.gif');

残念ながら、単純な js オブジェクト ルックアップの単純さは失われますが、それは、順序付けられたエンティティを持つために支払う代償です。

順序と dot.notation が絶対に必要な場合は、ルックアップ用のプレーンな js オブジェクトと順序用の配列を維持します。注意を払うことで、この 2 つは完全な完全性を維持することができます。

于 2013-02-01T12:22:23.533 に答える
0

この質問に対する私の回答を参照してください。基本的な順序付けられたハッシュテーブルを実装しました (ES 5+ のみ、ポリフィルを気にしませんでした)

于 2014-07-03T18:06:21.627 に答える