Reflect Metadata
是 ES7(ES2016)
的一个提案。当然,并没有通过,否则就能直接用了,注意:它是 ES6
中 Reflect API
的扩展。它主要用来在声明的时候添加和读取元数据。
设计目的
Reflect Metadata
的目的是给对象添加额外的信息,但是不影响对象的结构,这一点至关重要!也就是当我们给对象添加一些原始信息的时候,对象是不会有任何变化的,不会多 property
,也不会有 property
被修改,更不会删除已有的 property
。
实现原理
首先,对于一个对象来说,它可以有很多个metadata
,每一个 metadata
都有一个 key
,以及 metadata
的 value
,同时,相同对象下的 metadata
的 key
应该是唯一的,不可重复的。而且从设计目的出发,又不会修改对象。通过阅读源码,发现作者是通过维护一个 全局变量
的方式来实现的。
上核心代码:
const usePolyfill = typeof process === "object" && process.env && process.env["REFLECT_METADATA_USE_MAP_POLYFILL"] === "true"; const _Map: typeof Map = !usePolyfill && typeof Map === "function" && typeof Map.prototype.entries === "function" ? Map : CreateMapPolyfill(); const _WeakMap: typeof WeakMap = !usePolyfill && typeof WeakMap === "function" ? WeakMap : CreateWeakMapPolyfill(); const Metadata = new _WeakMap<any, Map<string | symbol | undefined, Map<any, any>>>();点击复制复制失败已复制
上述代码中 Metadata
就是作者维护的全局变量。(代码中有一些polyfill相关的,影响阅读,专注核心即可)
Metadata
是一个 WeakMap
类型,使用 WeakMap
而不是 Map
这个问题请转至笔记Javascript WeakMap。看起来三层 Map
会比较绕,我们从元数据的获取角度来看这个
结构:
Metadata.get(target).get(property).get(key)
其中:
target
:类property
:属性,如果是类的metadata
,这里是undefined
key
:metadata key
这时候就会看起来很清晰了,整个 reflect-metadata
库无非就是维护这个全局变量而已!
核心思想是有了,接下来看一下具体使用方式:Reflect Metadata用法