免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

從C#到TypeScript-裝飾器

從C#到TypeScript - 裝飾器

在C#里面如果想要不直接修改類或方法,但給類或方法添加一些額外的信息或功能,可以想到用Attribute,這是一個(gè)十分方便的功能裝飾器。
用TypeScript同樣也可以利用裝飾器來給類、函數(shù)、屬性以及參數(shù)添加附加功能,裝飾器是ES7的一個(gè)提案,在TypeScript里已經(jīng)有實(shí)現(xiàn)可用,不過需要在tsconfig.json里啟用experimentalDecorators

創(chuàng)新互聯(lián)是專業(yè)的射洪網(wǎng)站建設(shè)公司,射洪接單;提供成都網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行射洪網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

"compilerOptions": {
    ..., // other options
    "experimentalDecorators": true}

裝飾器介紹

TypeScript中裝飾器可以應(yīng)用到類、方法、屬性及函數(shù)參數(shù)上,而且可以同時(shí)應(yīng)用多個(gè)。
裝飾器的寫法是@name()()可以不要,也可以在里面寫一些參數(shù)。

@Testable
@Log('controller')class Controller{

    @GET
    getContent(@QueryParam arg: string): string{        return '';
    }
}

裝飾器的實(shí)現(xiàn)

裝飾器根據(jù)實(shí)現(xiàn)可以分兩種:
一種是不帶括號(hào),和屬性一樣,如@Testable

function Testable(target: Function) { // 類、方法、屬性、方法參數(shù)的參數(shù)各不相同
    //這里可以記錄一些信息到target,或者針對(duì)target做一些處理,如seal}

另外一種是帶括號(hào)的,和函數(shù)一樣,如@Log('controller'),實(shí)現(xiàn)函數(shù)里的參數(shù)就是括號(hào)里的參數(shù),而且需要返回一個(gè)function

function Log(name: string) { // name就是傳進(jìn)來的參數(shù)'controller'
    return function(target: Function) { // 類、方法、屬性、方法參數(shù)的參數(shù)各不相同
        // 這里可以根據(jù)name和target來做一些處理
    }
}

類裝飾器

上面的(target: Function)其實(shí)就是類的裝飾器參數(shù),指向的是類的構(gòu)造函數(shù),如果想給類加一個(gè)簡單的seal功能,可以這樣做:

function sealed(target: Function) {    Object.seal(target);    Object.seal(target.prototype);
}

@sealedclass Test{
    
}

Test.prototype.test = ''; // 運(yùn)行時(shí)出錯(cuò),不能添加

上面的sealed就是類的裝飾器,target指構(gòu)造函數(shù),類裝飾器就這么一個(gè)參數(shù)。

方法裝飾器

方法裝飾器的使用方法和類裝飾器類似,只是參數(shù)不一樣,方法裝飾器有三個(gè)參數(shù):

  1. 如果裝飾的是靜態(tài)方法,則是類的構(gòu)造函數(shù),如果是實(shí)例方法則是類的原型。

  2. 方法的名字。

  3. 方法的PropertyDescriptor
    PropertyDescriptor即屬性描述符,有
    configurable 是否可以配置,如動(dòng)態(tài)添加刪除函數(shù)屬性之類
    writable 是否可寫,可以用來設(shè)置只讀屬性
    enumerable 是否可枚舉,即是否能在for...in中能枚舉到
    value 對(duì)象或?qū)傩缘闹?/p>

有了這些參數(shù)就可以很好的給方法添加一些功能,比如下面實(shí)現(xiàn)類型WebApi里的Get的路由:

const Router = Symbol(); // 唯一key,用來存裝飾器的信息function GET(path?: string) { // GET帶了個(gè)可選參數(shù)
    return (target: any, name: string) => setMethodDecorator(target, name, 'GET', path);
}//把method和path存起來,路由查找的時(shí)候就可以用了function setMethodDecorator(target: any, name: string, method: string, path?: string){
    target[Router] = target[Router] || {};
    target[Router][name] = target[Router][name] || {};
    target[Router][name].method = method;
    target[Router][name].path = path;
}// 通過PropertyDescriptor來設(shè)置enumerablefunction Enumerable(enumerable: boolean) { 
    return (target: any, name: string, descriptor: PropertyDescriptor) => {
        descriptor.enumerable = enumerable;
    };
}class Controller{

    @GET
    @Enumerable(true)
    getContent(arg: string): string{        return '';
    }
}

參數(shù)裝飾器

方法參數(shù)同樣可以有裝飾器,同樣有三個(gè)參數(shù),前兩個(gè)參數(shù)和方法的一致,最后一個(gè)參數(shù)是所裝飾的參數(shù)的位置。
能過參數(shù)裝飾器可以給方法動(dòng)態(tài)的檢查或設(shè)置參數(shù)值,下面是檢查參數(shù)是否為空,為空則拋出異常。

const CheckNullKey = Symbol();const Router = Symbol();// 把CheckNull裝飾的參數(shù)存起來function CheckNull(target: any, name: string, index: number) {
    target[Router] = target[Router] || {};
    target[Router][name] = target[Router][name] || {};
    target[Router][name].params = target[Router][name].params || [];
    target[Router][name].params[index] = CheckNullKey;
}// 找出CheckNull的參數(shù),并檢查參數(shù)值,為空則拋異常,否則繼續(xù)執(zhí)行方法function Check(target: any, name: string, descriptor: PropertyDescriptor) {    let method = descriptor.value;
    descriptor.value = function () {        let params = target[Router][name].params;        if (params) {            for (let index = 0; index < params.length; index++) {                if (params[index] == CheckNullKey &&  // 找到CheckNull的參數(shù)并拋異常
                    (arguments[index] === undefined || arguments[index] === null)) {                    throw new Error("Missing required argument.");
                }
            }
        }        return method.apply(this, arguments);
    }
}class Controller{

    @Check
    getContent(@CheckNull id: string): string{        console.info(id);        return id;
    }
}new Controller().getContent(null); // error : Missing required argument.

屬性裝飾器

用法同上,參數(shù)只有兩個(gè),和類裝飾器的前兩個(gè)一樣,常用來標(biāo)識(shí)屬性的特性。

function Column(target: any, name: string) {    //把name存起來,這個(gè)column僅僅是標(biāo)識(shí)出來對(duì)應(yīng)數(shù)據(jù)庫中的列,常用在ORM框架中}class Table{

    @Column  
    name: string;
}

另外還有屬性訪問器的裝飾器,和方法基本一樣,同樣的三個(gè)參數(shù),不過同個(gè)屬性的getset只能有一個(gè)有,而且必須是先聲明的那個(gè)。

class User {    private _name: string;

    @Enumerable(true)    get name(){        return this._name;
    }    set name(value: string) {        this._name = value;
    }
}

多個(gè)裝飾器的執(zhí)行順序

一個(gè)聲明可以添加多個(gè)裝飾器,所以會(huì)有個(gè)執(zhí)行先后順序。
首先從上到下執(zhí)行裝飾器函數(shù),然后再從下往上應(yīng)用帶括號(hào)的裝飾器返回的函數(shù)。

function Test1(){    console.info('eval test1');    return function(target: any, name: string, descriptor: PropertyDescriptor){        console.info('apply test1');
    }
}function Test2(){    console.info('eval test2');    return function(target: any, name: string, descriptor: PropertyDescriptor){        console.info('apply test2');
    }
}class User1{

    @test1()
    @Test2()
    getName(){

    }
}

結(jié)果是:

eval test1eval test2
apply test2
apply test1

總之,裝飾器等于引入了天然的裝飾模式,給類,方法等添加額外功能。不過裝飾器目前還不算太穩(wěn)定,但是由于確實(shí)方便,已經(jīng)有成熟項(xiàng)目在使用了。

網(wǎng)頁題目:從C#到TypeScript-裝飾器
分享鏈接:http://m.newbst.com/article6/jocdig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供手機(jī)網(wǎng)站建設(shè)App開發(fā)全網(wǎng)營銷推廣網(wǎng)站設(shè)計(jì)網(wǎng)站制作網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)