Proxy融合Reflect

lxf2023-02-16 15:49:40

(1)序言

近期,在清查新项目上的一些管理权限难题,遇到了nest.js的一个API:"setMetaData" 。它是一个设定数据库(metadata)的装饰器。为了能弄明白,设定后元信息是在什么地方。我就去翻一下"setMetaData"的源代码。看了源代码后,便接触了 数据库 和 元编程(metaprogramming)。

那样,什么叫数据库?什么叫元编程呢?

(2)数据库

在日常日常生活,元信息是无处不在的。我还在阮一峰高手的blog下见到这么一句叙述:"元信息是用于描述数据的信息(Data that describes other data)" 。我们通过生活中的场景去认识它。平常观看一部电影时,大家在看电影的介绍时,而"介绍"它是数据库。还可以用自身来表示数据库,人人都有"名字"、"年纪"、"个子"、"性情"等,而这些都是数据库。

但在系统中,我们还可以把自己的生活当做一个数据库系统。而名字就是我们数据库表中的"name"字段名。而"name"它就是数据库。

做了网址SEO提升的同学都了解,HTML有一个文本文档级元数据元素,而keywords也是经常被用来提升页面的SEO的数据库,百度搜索引擎会依据keywords关键字去归因于。

Proxy融合Reflect

(3)元编程

"元编程能为你带来能够谷歌扩展程序个人能力"。元编程能够让你编辑程序的底层运作规则,同时还可以扩展和更加好的维修记录表。

ES6以后引进了一些常见的元编程有:Proxy、Reflect、Symbol等。在我们平常程序编写,常见Proxy融合Reflect来进行管理程序的运转标准

就像我们所看到的Vue3.0根据融合Proxy和Reflect去代理对象和反射面目标来达到响应式网站基本原理

看到这个,想必大家数据库和元编程有一定的明白了,下面根据nest.js的源代码进行。

(4)Reflect Metadata

以下属于nest.js设定数据库的需求场景:

Proxy融合Reflect

下面我们从nest.js源代码去分析setMetadata是如何达到的。

Proxy融合Reflect

选用Reflect.defineMetadata去定位一个数据库。而Reflect.defineMetadata 是 Reflect Metadata的办法。

Reflect Metadata是15年一个提议,如果想用Reflect Metadata就需要依靠三方包(reflect-metadata)。我们应该去组装一下该npm包:

npm i reflect-metadata

TS自然环境已经实现了@Reflect.metadata装饰器,我们可以通过建立index.ts文档编译程序一个事例。

Proxy融合Reflect

用tsc去编译程序一下以后可以获得后index.js,有了大家界定的数据库。

Proxy融合Reflect

可是tsc编译选项能通过打开emitDecoratorMetadata就会自动添加一些数据库。由于Reflect.metadata或是议案环节,因此还要打开另一个选择项experimentalDecorators。

Proxy融合ReflectProxy融合Reflect

编译程序后的结果得多三条数据库,各是总体目标的种类、目标参数类型、目标返回值类型。

在nest.js的setMetadata的实现本质就是Reflect metadata的API。

Proxy融合Reflect

setMetadata里的Reflect.defineMetadata便是界定一个数据库,数据库设定后确实存在总体目标上,其实就是类,或是目标上。

设定数据库后目标上都存在着[[Metadata]]特性,该属性一个 Map 目标。由于Reflect Metadata源代码上采用的算法设计是WeakMap。通常是WeakMap减轻引用计数(垃圾分类回收的一种方式)的特征。

而更多Reflect Metadata的办法能看文本文档。

rbuckton.github.io/reflect-met…

(5)总结

1. nest.js的setMetadata装饰器完成工作原理是Reflect Metadata。设定后元信息是存有类或是目标上。

  1. nest.js的Controller、Module、Service等一些装饰器也是通过Reflect Metadata给类和对象加上数据库,随后复位时取下数据库做依靠扫描仪,创建对象后放进IOC的容器中。

最终你就会发现,完成nest.js的基本原理和数据库(metadata)、元编程(metaprogramming)有密切的联系。