摘要:慶幸的是,已經支持反射機制,來看看這個特性吧元數據反射可以通過安裝包來使用元數據反射的若要使用它,我們需要在中設置為,同時添加的引用,同時加載文件。復雜類型序列化的團隊為復雜類型的元數據序列化做出了努力。
本篇內容包括如下部分:
為什么JavaScript中需要反射
元數據反射API
基本類型序列化
復雜類型序列化
為什么JavaScript中需要反射?關于反射的概念,摘自百度百科
在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過采用某種機制來實現對自己行為的描述(self-representation)和監測(examination),并能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。
可見反射機制對于依賴注入、運行時類型斷言、測試是非常有用的,同時隨著基于JavaScript的應用做的越來越大,使得我們希望有一些工具和特性可以用來應對增長的復雜度,例如控制反轉,運行時類型斷言等。但由于JavaScript語言中沒有反射機制,所以導致這些東西要么沒法實現,要么實現的不如C#或Java語言實現的強大。
強大的反射API允許我們可以在運行時測試一個未知的類,以及找到關于它的任何信息,包括:名稱、類型、接口等。雖然可以使用諸如Object.getOwnPropertyDescriptor()和Object.keys()查詢到一些信息,但我們需要反射來實現更強大的開發工具。慶幸的是,TypeScript已經支持反射機制,來看看這個特性吧
元數據反射API可以通過安裝reflect-metadata包來使用元數據反射的API
npm install reflect-metadata;
若要使用它,我們需要在tsconfig.json中設置emitDecoratorMetadata為true,同時添加reflect-metadata.d.ts的引用,同時加載Reflect.js文件。然后我們來實現裝飾器并使用反射元數據設計的鍵值,目前可用的有:
類型元數據:design:type
參數類型元數據:design:paramtypes
返回類型元數據:design:returntype
我們來通過一組例子來說明
1)獲取類型元數據首先聲明如下的屬性裝飾器:
function logType(target : any, key : string) { var t = Reflect.getMetadata("design:type", target, key); console.log(`${key} type: ${t.name}`); }
接下來將其應用到一個類的屬性上,以獲取其類型:
class Demo{ @logType public attr1 : string; }
這個例子將會在控制臺中打印如下信息:
attr1 type: String2) 獲取參數類型元數據
聲明參數裝飾器如下:
function logParamTypes(target : any, key : string) { var types = Reflect.getMetadata("design:paramtypes", target, key); var s = types.map(a => a.name).join(); console.log(`${key} param types: ${s}`); }
然后將它應用在一個類方法的參數上,用以獲取所裝飾參數的類型:
class Foo {} interface IFoo {} class Demo{ @logParameters param1 : string, param2 : number, param3 : Foo, param4 : { test : string }, param5 : IFoo, param6 : Function, param7 : (a : number) => void, ) : number { return 1 } }
這個例子的執行結果是:
doSomething param types: String, Number, Foo, Object, Object, Function, Function3) 獲取返回類型元數據
同樣的我們可以使用"design:returntype"元數據鍵值,來獲取一個方法的返回類型:
Reflect.getMetadata("design:returntype", target, key);基本類型序列化
讓我們回看上面關于"design:paramtypes"的例子,注意到接口IFoo和對象字面量{test: string}被序列化為Object,這是因為TypeScript僅支持基本類型的序列化,基本類型序列化規則如下:
number序列化為Number
string序列化為String
boolean序列化為Boolean
any序列化為Object
void序列化為undefined
Array序列化為Array
元組Tuple序列化為Array
類class序列化為類的構造函數
枚舉Enum序列化為Number
剩下的所有其他類型都被序列化為Object
接口和對象字面量可能在之后的復雜類型序列化中會被做具體的處理。
復雜類型序列化TypeScript的團隊為復雜類型的元數據序列化做出了努力。上面列出的序列化規則對基本類型依然適用,但對復雜類型提出了不同的序列化邏輯。如下是通過一個例子來描述所有可能的類型:
interface _Type { /** * Describes the specific shape of the type. * @remarks * One of: "typeparameter", "typereference", "interface", "tuple", "union" or "function". */ kind: string; }
我們也可以找到用于描述每種可能類型的類,例如用于序列化通用接口interface foo
// 描述一個通用接口 interface InterfaceType extends _Type { kind: string; // "interface" // 通用類型參數. 可能為undefined. typeParameters?: TypeParameter[]; // 實現的接口. implements?: Type[]; // 類型的成員 可能為undefined. members?: { [key: string | symbol | number]: Type; }; // 類型的調用標識. 可能為undefined. call?: Signature[]; // 類型的構造標識. 可能為undefined. construct?: Signature[]; // 類型的索引標識. 可能為undefined. index?: Signature[]; }
這里有一個屬性指出實現了哪些接口
// 實現的接口 implements?: Type[];
這種信息可以用來在運行時驗證一個實例是否實現了特定的接口,而這個功能對于一個依賴翻轉容器特別的有用。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101540.html
摘要:使用裝飾器的方法很簡單在裝飾器名前加字符,寫在想要裝飾的方法上,類似寫注釋的方式裝飾器實際上是一個函數,入參為所裝飾的方法,返回值為裝飾后的方法。經過裝飾過的方法,它依然按照原來的方式執行,只是額外執行了附件的裝飾器函數的功能。 讓我來深入地了解一下TypeScript對于裝飾器模式的實現,以及反射與依賴注入等相關特性。 在Typescript的源代碼中,可以看到裝飾器能用來修飾cla...
摘要:可見參數裝飾器函數需要個參數被裝飾類的原型,裝飾參數所屬的方法名,參數的索引。參數裝飾器不應當用來修改構造器方法或屬性的行為,它只應當用來產生某種元數據。一旦元數據被創建,我們便可以用其它的裝飾器去讀取它。 之前已經分別介紹了方法裝飾器、屬性裝飾器和類裝飾器,這篇文章我們來繼續關注這些話題: 參數裝飾器 裝飾器工廠 我們將圍繞以下這個例子,來探討這些概念: class Person...
摘要:值得注意的是,的返回值復寫了原始的構造函數,原因是類裝飾器必須返回一個構造器函數。原始構造函數的原型被復制給的原型,以確保在創建一個的新實例時,操作符如愿以償,具體原因可參考鄙人另一篇文章原型與對象。 上一篇文章中,我們討論了TypeScript源碼中關于方法裝飾器的實現,搞明白了如下幾個問題: 裝飾器函數是如何被調用的? 裝飾器函數參數是如何傳入的? __decorate函數干了...
摘要:第章元編程與注解反射反射是在運行時獲取類的函數方法屬性父類接口注解元數據泛型信息等類的內部信息的機制。本章介紹中的注解與反射編程的相關內容。元編程本質上是一種對源代碼本身進行高層次抽象的編碼技術。反射是促進元編程的一種很有價值的語言特性。 第12章 元編程與注解、反射 反射(Reflection)是在運行時獲取類的函數(方法)、屬性、父類、接口、注解元數據、泛型信息等類的內部信息的機...
摘要:使用元數據包中包含了中每一個被建模類對應的接口。任何對象的元數據是使用的實現來表示的。加載模型的序列化形式是個在運行期間獲取元數據的有效方法。反射提供一個反射式,可以檢查對象的元數據以及一般地訪問和操縱數據。 使用元數據 Java包org.eclipse.emf.ecore中包含了Ecore中每一個被建模類對應的接口。任何EMF對象的元數據是使用Ecore的實現(implement...
閱讀 1432·2021-11-25 09:43
閱讀 2029·2021-07-26 23:38
閱讀 740·2019-08-30 15:53
閱讀 2280·2019-08-30 15:43
閱讀 1167·2019-08-29 18:40
閱讀 1970·2019-08-26 13:28
閱讀 1973·2019-08-23 18:20
閱讀 542·2019-08-23 15:07