8

メタデータのキーと値のペアを任意の JavaScript オブジェクトに追加したいと考えています。このメタデータは、メタデータを認識しないコードに影響を与えるべきではありません。つまり、たとえば

JSON.stringify(obj) === JSON.stringify(obj.WithMetaData('key', 'value'))

メタデータ対応コードは、キーでデータを取得できる必要があります。つまり、

obj.WithMetaData('key', 'value').GetMetaData('key') === 'value'

node.jsでそれを行う方法はありますか? もしそうなら、それはString and evenNumberのような組み込み型で動作しますか? (編集考えてみると、数字のような実際のプリミティブは気にしませんが、文字列インスタンスにそれがあるといいでしょう)。

いくつかの背景: 私がやろうとしているのは、オブジェクト自体を使用してオブジェクトから派生した値をキャッシュすることです。

  • メタデータを認識しないコードに対して、メタデータが強化されたオブジェクトは、メタのない元のオブジェクトと同じように見えます
  • 導出された値を必要とするコードは、すでにキャッシュされている場合、メタデータから取得できます
  • キャッシュはオブジェクトと一緒にガベージコレクションを取得します

もう 1 つの方法は、ハッシュ テーブルをキャッシュとともにどこかに格納することですが、オブジェクトがいつガベージ コレクションされるかはわかりません。キャッシュがリークしないように、すべてのオブジェクト インスタンスを手動で処理する必要があります。

(ところで、clojure にはこの機能があります: http://clojure.org/metadata )

4

4 に答える 4

8

ECMA5 の新しいオブジェクト プロパティ API を使用して、列挙には表示されないが取得可能なオブジェクトのプロパティを格納できます。

var myObj = {};
myObj.real_property = 'hello';
Object.defineProperty(myObj, 'meta_property', {value: 'some meta value'});
for (var i in myObj)
    alert(i+' = '+myObj[i]); //only one property - @real_property
alert(myObj.meta_property); //"some meta value"

詳細はこちら:リンク

ただし、文字列や数値などのプリミティブ型ではこれを行うことはできず、複雑な型でのみ行うことができます。

[編集]

もう 1 つのアプローチは、データ型のプロトタイプを利用してメタを格納することです。(警告、先にハックしてください)。したがって、文字列の場合:

String.prototype.meta = {};
String.prototype.addMeta = function(name, val) { this.meta[name] = val; }
String.prototype.getMeta = function(name) { return this.meta[name]; };
var str = 'some string value';
str.addMeta('meta', 'val');
alert(str.getMeta('meta'));

しかし、これは明らかに理想的ではありません。1 つには、文字列が収集またはエイリアス化された場合 (単純なデータ型は参照ではなく値によってコピーされるため)、このメタが失われます。正直に言うと、最初のアプローチだけが実際の環境でマイレージを持っています。

于 2012-07-31T13:18:19.930 に答える
1

JSON には「コメント」システムはありません。期待できる最善の方法は、ありそうもない名前のプロパティを追加し、メタデータを含むそのキーを追加することです。メタデータであることがわかっている場合は、メタデータを読み戻すことができますが、他のセットアップでは別のプロパティとして認識されます。そして、誰かが使用する場合for..in...

于 2012-07-31T13:16:14.980 に答える
1

メタデータを「プライベート」変数として追加できます!?

var Obj = function (meta) {
    var meta = meta;
    this.getMetaData = function (key) {
        //do something with the meta object
        return meta;
    };
};
var ins_ob = new Obj({meta:'meta'});
var ins_ob2 = new Obj();
if(JSON.stringify(ins_ob) === JSON.stringify(ins_ob2)) {
    console.log('hoorai');
};
于 2012-07-31T13:30:29.773 に答える