Is there a way to add metadata to JavaScript objects?

I would like to add key-value metadata pairs to arbitrary JavaScript objects. This metadata should not affect code that does not know metadata, which means, for example,

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

Code supporting MetaData should be able to retrieve data using a key, i.e.

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

Is there a way to do this - in node.js? If so, does it work with built-in types such as String and evenNumber ? ( Change ). I think that I'm not interested in real primitives, such as numbers, but it would be nice to have this for string instances).

Some information: what I'm trying to do is cache values ​​that are produced from an object with the object itself, so

  • for metadata that does not know the code, an object enriched with metadata will look the same as the original object without meta
  • code that needs derived values ​​can infer it from metadata if it is already cached
  • the cache will receive garbage collected near the object

Another way is to store a hash table with caches somewhere, but you will never know when an object receives garbage collection. Each instance of the object will need to be taken care of manually so that caches do not leak.

(btw clojure has this function: http://clojure.org/metadata )

+5
source share
4 answers

You can use the properties API of the new ECMA5 properties to store properties of objects that will not be displayed in the enumeration, but can nevertheless be restored.

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"

:

, , .

[EDIT]

. (, ). , :

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'));

. -, ( , ), . , .

+7

ES6 Map WeakMap. node, node --harmony javascript Chrome ( Firefox). WeakMaps , , / . , :

function createStorage(creator){
  creator = creator || Object.create.bind(null, null, {});
  var map = new Map;
  return function storage(o, v){
    if (1 in arguments) {
      map.set(o, v);
    } else {
      v = map.get(o);
      if (v == null) {
        v = creator(o);
        map.set(o, v);
      }
    }
    return v;
  };
}

:

var _ = createStorage();

_(someObject).meta= 'secret';
_(5).meta = [5];
var five = new Number(5);
_(five).meta = 'five';

console.log(_(someObject).name);
console.log(_(5).meta);
console.log(_(five).meta);

:

var _ = createStorage(function(o){ return new Backing(o) });

function Backing(o){
  this.facade = o;
}
Backing.prototype.doesStuff = function(){
  return 'real value';
}

function Facade(){
  _(this);
}
Facade.prototype.doSomething = function doSomething(){
  return _(this).doesStuff();
}
+4

"private"!?

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');
};
+1

JSON . , , , . , , . - for..in...

0
source

All Articles