您好,登錄后才能下訂單哦!
本篇內容主要講解“JavaScript中的元數據怎么使用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JavaScript中的元數據怎么使用”吧!
在 ES6
的規范當中,ES6
支持元編程,核心是因為提供了對 Proxy
和 Reflect
對象的支持,簡單來說這個 API
的作用就是可以實現對變量操作的函數化,也就是反射。
元數據是指附加在對象、類、方法、屬性、參數上的數據,它可以用來幫助實現某種業務功能需要用到的數據。
Reflect-metadata-
是 ES7
的一個提案,它主要用來聲明的時候添加和讀取元數據,Typescript
在 1.5+
的版本已經支持它,你只需要:
npm i reflect-metadata --save
緊接著你要在 tsconfig.json
文件中添加以下配置:
{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true } }
該方法是一個函數重載,它既可以接收三個參數,也可以是四個參數,具體定義如下所示:
function defineMetadata(metadataKey: any, metadataValue: any, target: Object): void; function defineMetadata(metadataKey: any, metadataValue: any, target: Object, propertyKey: string | symbol): void;
它們的參數分別是:
metadataKey
: 用于存儲和檢索元數據的鍵;
metadataValue
: 元數據的值;
target
: 要在其上定義元數據的目標對象;
propertyKey
: 目標對象上的屬性;
有存值的就有取值的,這個方法也是一個函數重載,它的具體定義如下所示:
function getMetadata(metadataKey: any, target: Object, propertyKey: string | symbol): any; function getOwnMetadata(metadataKey: any, target: Object): any;
它的具體使用如下所示:
import "reflect-metadata"; const moment = { address: "廣州" }; Reflect.defineMetadata("method", "hi,叼毛,你上班是不是在摸魚", moment); console.log(Reflect.getMetadata("method", moment)); // hi,叼毛,你上班是不是在摸魚 Reflect.defineMetadata("method", "hi,靚仔,買菜嗎", moment, moment.address); console.log(Reflect.getMetadata("method", moment, moment.address)); // hi,靚仔,買菜嗎
Reflect.metadata(...)
方法的可以用于類或者類屬性上,它的具體定義如下所示:
function metadata( metadataKey: any, metadataValue: any ): { (target: Function): void; (target: Object, propertyKey: string | symbol): void; };
Reflect.metadata
當作 Decorator
使用,當修飾類時,在類上添加元數據,當修飾類屬性時,在類原型的屬性上添加元數據:
import "reflect-metadata"; @Reflect.metadata("inClass", "哇哈哈哈哈") class Test { @Reflect.metadata("inMethod", "我要喝喜之郎,我要當太空人") public hello(): string { return "hello world"; } } console.log(Reflect.getMetadata("inClass", Test)); // 哇哈哈哈哈 console.log(Reflect.getMetadata("inMethod", new Test(), "hello")); // 我要喝喜之郎,我要當太空人
在這里可能會有人就好奇了,這里面的方法怎么和上面的不一樣啊,上面的是 defineMetadata(...)
,而這里直接用的 metadata(...)
,這是為什么呢?
答案是 defineMetadata(...)
它要確定你要是在哪里定義的元數據,而后者是直接以裝飾器的方式調用,它已經明確知道了你就是給這個類來定義的元數據。
我們可以通過 Reflect.getMetadata
方法來獲取屬性類型,并且對該屬性進行賦值,如下操作所示:
import "reflect-metadata"; function Prop(): PropertyDecorator { return (target, key: string) => { const type = Reflect.getMetadata("design:type", target, key); console.log(`${key} type: ${type.name}`); target[key] = "moment"; }; } class SomeClass { @Prop() public nickname!: string; } console.log(new SomeClass().nickname); // moment
例如在 vue-property-decorator
中通過使用 Reflect.getMetadata
API,Prop
Decorator 能獲取屬性類型傳至 Vue
,簡要代碼如下:
import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @PropSync('name', { type: String }) syncedName!: string }
這樣的寫法就等同于以下代碼所示:
export default { props: { name: { type: String, }, }, computed: { syncedName: { get() { return this.name }, set(value) { this.$emit('update:name', value) }, }, }, }
除了能獲取屬性類型以外,通過 Reflect.getMetadata("design:paramtypes", target, key)
和 Reflect.getMetadata("design:returntype", target, key)
可以分別獲取函數參數類型和返回值類型,具體代碼如下所示:
import "reflect-metadata"; function Func(): PropertyDecorator { return (target, key: string) => { console.log(Reflect.getMetadata("design:paramtypes", target, key)); // 函數參數類型 console.log(Reflect.getMetadata("design:returntype", target, key)); // 返回值類型 }; } class SomeClass { @Func() moment(value: boolean): string { return " "; } }
除了能獲取類型信息外,常用與自定義 metadataKey
,并在合適的實際獲取它的值,具體實例代碼如下所示:
import "reflect-metadata"; function classDecorator(): ClassDecorator { return (target) => { Reflect.defineMetadata("class", "類裝飾器", target); }; } function methodDecorator(): MethodDecorator { return (target, key, descriptor) => { Reflect.defineMetadata("method", "方法裝飾器", target, key); }; } @classDecorator() class SomeClass { @methodDecorator() someMethod() {} } console.log(Reflect.getMetadata("class", SomeClass)); // 類裝飾器 console.log(Reflect.getMetadata("method", new SomeClass(), "someMethod")); // 方法裝飾器
到此,相信大家對“JavaScript中的元數據怎么使用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。