国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

裝飾器與元數(shù)據(jù)反射(4)元數(shù)據(jù)反射

gaosboy / 550人閱讀

摘要:慶幸的是,已經(jīng)支持反射機制,來看看這個特性吧元數(shù)據(jù)反射可以通過安裝包來使用元數(shù)據(jù)反射的若要使用它,我們需要在中設(shè)置為,同時添加的引用,同時加載文件。復(fù)雜類型序列化的團隊為復(fù)雜類型的元數(shù)據(jù)序列化做出了努力。

本篇內(nèi)容包括如下部分:

為什么JavaScript中需要反射

元數(shù)據(jù)反射API

基本類型序列化

復(fù)雜類型序列化

為什么JavaScript中需要反射?

關(guān)于反射的概念,摘自百度百科

在計算機科學(xué)領(lǐng)域,反射是指一類應(yīng)用,它們能夠自描述和自控制。也就是說,這類應(yīng)用通過采用某種機制來實現(xiàn)對自己行為的描述(self-representation)和監(jiān)測(examination),并能根據(jù)自身行為的狀態(tài)和結(jié)果,調(diào)整或修改應(yīng)用所描述行為的狀態(tài)和相關(guān)的語義。

可見反射機制對于依賴注入、運行時類型斷言、測試是非常有用的,同時隨著基于JavaScript的應(yīng)用做的越來越大,使得我們希望有一些工具和特性可以用來應(yīng)對增長的復(fù)雜度,例如控制反轉(zhuǎn),運行時類型斷言等。但由于JavaScript語言中沒有反射機制,所以導(dǎo)致這些東西要么沒法實現(xiàn),要么實現(xiàn)的不如C#Java語言實現(xiàn)的強大。

強大的反射API允許我們可以在運行時測試一個未知的類,以及找到關(guān)于它的任何信息,包括:名稱、類型、接口等。雖然可以使用諸如Object.getOwnPropertyDescriptor()Object.keys()查詢到一些信息,但我們需要反射來實現(xiàn)更強大的開發(fā)工具。慶幸的是,TypeScript已經(jīng)支持反射機制,來看看這個特性吧

元數(shù)據(jù)反射API

可以通過安裝reflect-metadata包來使用元數(shù)據(jù)反射的API

npm install reflect-metadata;

若要使用它,我們需要在tsconfig.json中設(shè)置emitDecoratorMetadatatrue,同時添加reflect-metadata.d.ts的引用,同時加載Reflect.js文件。然后我們來實現(xiàn)裝飾器并使用反射元數(shù)據(jù)設(shè)計的鍵值,目前可用的有:

類型元數(shù)據(jù):design:type

參數(shù)類型元數(shù)據(jù):design:paramtypes

返回類型元數(shù)據(jù):design:returntype

我們來通過一組例子來說明

1)獲取類型元數(shù)據(jù)

首先聲明如下的屬性裝飾器:

function logType(target : any, key : string) {
    var t = Reflect.getMetadata("design:type", target, key);
    console.log(`${key} type: ${t.name}`);
}

接下來將其應(yīng)用到一個類的屬性上,以獲取其類型:

class Demo{ 
    @logType
    public attr1 : string;
}

這個例子將會在控制臺中打印如下信息:

attr1 type: String
2) 獲取參數(shù)類型元數(shù)據(jù)

聲明參數(shù)裝飾器如下:

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}`);
} 

然后將它應(yīng)用在一個類方法的參數(shù)上,用以獲取所裝飾參數(shù)的類型:

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
    }
}

這個例子的執(zhí)行結(jié)果是:

doSomething param types: String, Number, Foo, Object, Object, Function, Function
3) 獲取返回類型元數(shù)據(jù)

同樣的我們可以使用"design:returntype"元數(shù)據(jù)鍵值,來獲取一個方法的返回類型:

Reflect.getMetadata("design:returntype", target, key);
基本類型序列化

讓我們回看上面關(guān)于"design:paramtypes"的例子,注意到接口IFoo和對象字面量{test: string}被序列化為Object,這是因為TypeScript僅支持基本類型的序列化,基本類型序列化規(guī)則如下:

number序列化為Number

string序列化為String

boolean序列化為Boolean

any序列化為Object

void序列化為undefined

Array序列化為Array

元組Tuple序列化為Array

class序列化為類的構(gòu)造函數(shù)

枚舉Enum序列化為Number

剩下的所有其他類型都被序列化為Object

接口和對象字面量可能在之后的復(fù)雜類型序列化中會被做具體的處理。

復(fù)雜類型序列化

TypeScript的團隊為復(fù)雜類型的元數(shù)據(jù)序列化做出了努力。上面列出的序列化規(guī)則對基本類型依然適用,但對復(fù)雜類型提出了不同的序列化邏輯。如下是通過一個例子來描述所有可能的類型:

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"

  // 通用類型參數(shù). 可能為undefined.
  typeParameters?: TypeParameter[];

  // 實現(xiàn)的接口.
  implements?: Type[];

  // 類型的成員 可能為undefined.
  members?: { [key: string | symbol | number]: Type; };

  // 類型的調(diào)用標(biāo)識. 可能為undefined.
  call?: Signature[];

  // 類型的構(gòu)造標(biāo)識. 可能為undefined.
  construct?: Signature[];

  // 類型的索引標(biāo)識. 可能為undefined.
  index?: Signature[];
}

這里有一個屬性指出實現(xiàn)了哪些接口

// 實現(xiàn)的接口
implements?: Type[];

這種信息可以用來在運行時驗證一個實例是否實現(xiàn)了特定的接口,而這個功能對于一個依賴翻轉(zhuǎn)容器特別的有用。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/101540.html

相關(guān)文章

  • 裝飾數(shù)據(jù)反射(1)方法裝飾

    摘要:使用裝飾器的方法很簡單在裝飾器名前加字符,寫在想要裝飾的方法上,類似寫注釋的方式裝飾器實際上是一個函數(shù),入?yún)樗b飾的方法,返回值為裝飾后的方法。經(jīng)過裝飾過的方法,它依然按照原來的方式執(zhí)行,只是額外執(zhí)行了附件的裝飾器函數(shù)的功能。 讓我來深入地了解一下TypeScript對于裝飾器模式的實現(xiàn),以及反射與依賴注入等相關(guān)特性。 在Typescript的源代碼中,可以看到裝飾器能用來修飾cla...

    xiaochao 評論0 收藏0
  • 裝飾數(shù)據(jù)反射(3)參數(shù)裝飾

    摘要:可見參數(shù)裝飾器函數(shù)需要個參數(shù)被裝飾類的原型,裝飾參數(shù)所屬的方法名,參數(shù)的索引。參數(shù)裝飾器不應(yīng)當(dāng)用來修改構(gòu)造器方法或?qū)傩缘男袨椋粦?yīng)當(dāng)用來產(chǎn)生某種元數(shù)據(jù)。一旦元數(shù)據(jù)被創(chuàng)建,我們便可以用其它的裝飾器去讀取它。 之前已經(jīng)分別介紹了方法裝飾器、屬性裝飾器和類裝飾器,這篇文章我們來繼續(xù)關(guān)注這些話題: 參數(shù)裝飾器 裝飾器工廠 我們將圍繞以下這個例子,來探討這些概念: class Person...

    Barry_Ng 評論0 收藏0
  • 裝飾數(shù)據(jù)反射(2)屬與類性裝飾

    摘要:值得注意的是,的返回值復(fù)寫了原始的構(gòu)造函數(shù),原因是類裝飾器必須返回一個構(gòu)造器函數(shù)。原始構(gòu)造函數(shù)的原型被復(fù)制給的原型,以確保在創(chuàng)建一個的新實例時,操作符如愿以償,具體原因可參考鄙人另一篇文章原型與對象。 上一篇文章中,我們討論了TypeScript源碼中關(guān)于方法裝飾器的實現(xiàn),搞明白了如下幾個問題: 裝飾器函數(shù)是如何被調(diào)用的? 裝飾器函數(shù)參數(shù)是如何傳入的? __decorate函數(shù)干了...

    Shisui 評論0 收藏0
  • 第12章 編程與注解、反射 《Kotlin 項目實戰(zhàn)開發(fā)》

    摘要:第章元編程與注解反射反射是在運行時獲取類的函數(shù)方法屬性父類接口注解元數(shù)據(jù)泛型信息等類的內(nèi)部信息的機制。本章介紹中的注解與反射編程的相關(guān)內(nèi)容。元編程本質(zhì)上是一種對源代碼本身進行高層次抽象的編碼技術(shù)。反射是促進元編程的一種很有價值的語言特性。 第12章 元編程與注解、反射 反射(Reflection)是在運行時獲取類的函數(shù)(方法)、屬性、父類、接口、注解元數(shù)據(jù)、泛型信息等類的內(nèi)部信息的機...

    joyqi 評論0 收藏0
  • EMF學(xué)習(xí)筆記(二)——使用EMF編程——開發(fā)數(shù)據(jù)

    摘要:使用元數(shù)據(jù)包中包含了中每一個被建模類對應(yīng)的接口。任何對象的元數(shù)據(jù)是使用的實現(xiàn)來表示的。加載模型的序列化形式是個在運行期間獲取元數(shù)據(jù)的有效方法。反射提供一個反射式,可以檢查對象的元數(shù)據(jù)以及一般地訪問和操縱數(shù)據(jù)。 使用元數(shù)據(jù)   Java包org.eclipse.emf.ecore中包含了Ecore中每一個被建模類對應(yīng)的接口。任何EMF對象的元數(shù)據(jù)是使用Ecore的實現(xiàn)(implement...

    Jiavan 評論0 收藏0

發(fā)表評論

0條評論

gaosboy

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<