rbuckton / reflect-metadata

Prototype for a Metadata Reflection API for ECMAScript
https://rbuckton.github.io/reflect-metadata
Apache License 2.0
3.21k stars 184 forks source link

What is Metadata? #86

Open mikhailrojo opened 6 years ago

mikhailrojo commented 6 years ago

Can I ask what is metadata exactly? I haven't found anywhere any good description, only methods JsDoc.

According to Metadata Proposal you offer to add to any JS Object unreachable property [[Metadata]]. But anyone could read and write to it with specialized methods? Like 'defineMetadata', 'getOwnMetadata'? So it is more like getter/setter from OOP without direct access to property.

So I can make something like this to copy the behavior?


//structure will look like: 
const obj = {};

obj['Metadata'] = {
  customProperty1: {
    property: 'someValue'
  }
}
// Methods would look like this: 
Object.prototype.defineMetadata = function(metadataKey, metadataValue, target, key) {
  this['metadata'][metadataKey] = {key: metadataValue};
}
linonetwo commented 6 years ago

I think metadata can be used for runtime type check, likes io-ts and flow-runtime. And can also be used for some matching, like function overload or so?

linonetwo commented 6 years ago

@MuYunyun I was guessing. See flow-runtime document's annotate part https://github.com/codemix/flow-runtime/tree/master/packages/babel-plugin-flow-runtime#options

They annotate the function with metadata:

import t from 'flow-runtime';
const add = t.annotate(
  (a, b) => a + b,
  t.function(
    t.param('a', t.number()),
    t.param('b', t.number()),
    t.return(t.number())
  )
);
MuYunyun commented 6 years ago

@mikhailrojo

the simply code of Reflect.defineMetadata(metadataKey, metadataValue, target[, propertyKey]) as follow:

const Metadata = new WeakMap()

function defineMetadata(metadataKey, metadataValue, target, propertyKey) {
  metadataMap = new Map()
  metadataMap.set(metadataKey, metadataValue)
  targetMetadata = new Map()
  targetMetadata.set(propertyKey, metadataMap)
  Metadata.set(target, targetMetadata)
}

the simply code of Reflect.getOwnMetadata(metadataKey, target[, propertyKey]) as follow:

function getOwnMetadata(metadataKey, target, propertyKey) {
  var targetMetadata = Metadata.get(target)  
  var metadataMap = targetMetadata.get(propertyKey)
  return metadataMap.get(metadataKey)
}

we can notice it use WeakMap structure for one time, and the Map structure for two times.

So the Metadata is a WeakMap structure.