日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Angular 2 Decorators - 1

發(fā)布時(shí)間:2023/12/4 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Angular 2 Decorators - 1 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在我們深入了解 Angular 2 中 @NgModule、@Component、@Injectable 等常見的裝飾器之前,我們要先了解 TypeScript 中的裝飾器。裝飾器是一個(gè)非??岬奶匦?#xff0c;最早出現(xiàn)在 Google 的 AtScript 中,它出現(xiàn)的目的是為了讓開發(fā)者,開發(fā)出更容易維護(hù)、更容易理解的 Angular 代碼。令人興奮的是,在2015年 Angular 團(tuán)隊(duì)跟 MicroSoft 的 TypeScript 團(tuán)隊(duì)經(jīng)過數(shù)月的的交流,最終決定采用 TypeScript 來重寫 Angular 2 項(xiàng)目 。

裝飾器是什么

  • 它是一個(gè)表達(dá)式

  • 該表達(dá)式被執(zhí)行后,返回一個(gè)函數(shù)

  • 函數(shù)的入?yún)⒎謩e為 targe、name 和 descriptor

  • 執(zhí)行該函數(shù)后,可能返回 descriptor 對(duì)象,用于配置 target 對(duì)象 

裝飾器的分類

  • 類裝飾器 (Class decorators)

  • 屬性裝飾器 (Property decorators)

  • 方法裝飾器 (Method decorators)

  • 參數(shù)裝飾器 (Parameter decorators)

TypeScript 類裝飾器

類裝飾器聲明:

declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void

類裝飾器顧名思義,就是用來裝飾類的。它接收一個(gè)參數(shù):

  • target: TFunction - 被裝飾的類

看完第一眼后,是不是感覺都不好了。沒事,我們馬上來個(gè)例子:

function Greeter(target: Function): void {target.prototype.greet = function (): void {console.log('Hello!');} }@Greeter class Greeting {constructor() {// 內(nèi)部實(shí)現(xiàn)} }let myGreeting = new Greeting(); myGreeting.greet(); // console output: 'Hello!';

上面的例子中,我們定義了 Greeter 類裝飾器,同時(shí)我們使用了 @Greeter 新的語法,來使用裝飾器。

(備注:讀者可以直接復(fù)制上面的代碼,在 TypeScript Playground 中運(yùn)行查看結(jié)果)。

有的讀者可能想問,例子中總是輸出 Hello! ,能自定義輸出的問候語么 ?這個(gè)問題很好,答案是可以的。具體實(shí)現(xiàn)如下:

function Greeter(greeting: string) {return function(target: Function) {target.prototype.greet = function(): void {console.log(greeting);}} }@Greeter('您好') class Greeting {constructor() {// 內(nèi)部實(shí)現(xiàn)} }let myGreeting = new Greeting(); myGreeting.greet(); // console output: '您好!';

TypeScript 屬性裝飾器

屬性裝飾器聲明:

declare type PropertyDecorator = (target:Object, propertyKey: string | symbol ) => void;

屬性裝飾器顧名思義,用來裝飾類的屬性。它接收兩個(gè)參數(shù):

  • target: Object - 被裝飾的類

  • propertyKey:string | symbol - 被裝飾類的屬性名

趁熱打鐵,馬上來個(gè)例子熱熱身:

function LogChanges(target: Object, key: string) {var propertyValue: string = this[key];if(delete this[key]) {Object.defineProperty(target, key, {get: function () {return propertyValue;},set: function(newValue) {propertyValue = newValue;console.log(`${key} is now ${propertyValue}`);}});} }class Fruit {@LogChangesname: string; }let fruit = new Fruit(); fruit.name = 'apple'; // console output: 'name is now apple' fruit.name = 'banana'; // console output: 'name is now banana'

那么問題來了,如果用戶想在屬性變化的時(shí)候,自動(dòng)刷新頁面,而不是簡單地在控制臺(tái)輸出消息,那要怎么辦?我們能不能參照類裝飾器自定義問候語的方式,來實(shí)現(xiàn)監(jiān)測屬性變化的功能。具體實(shí)現(xiàn)如下:

function LogChanges(callbackObject: any) {return function(target: Object, key: string): void {var propertyValue: string = this[key];if(delete this[key]) {Object.defineProperty(target, key, {get: function () {return propertyValue;},set: function(newValue) {propertyValue = newValue;callbackObject.onchange.call(this, propertyValue);}});}} }class Fruit {@LogChanges({onchange: function(newValue: string): void {console.log(`The fruit is ${newValue} now`);}})name: string; }let fruit = new Fruit(); fruit.name = 'apple'; // console output: 'The fruit is apple now' fruit.name = 'banana'; // console output: 'The fruit is banana now'

TypeScript 方法裝飾器

方法裝飾器聲明:

declare type MethodDecorator = <T>(target:Object, propertyKey: string | symbol, descriptor: TypePropertyDescript<T>) => TypedPropertyDescriptor<T> | void;

方法裝飾器顧名思義,用來裝飾類的屬性。它接收三個(gè)參數(shù):

  • target: Object - 被裝飾的類

  • propertyKey: string | symbol - 方法名

  • descriptor: TypePropertyDescript - 屬性描述符

廢話不多說,直接上例子:

function LogOutput(tarage: Function, key: string, descriptor: any) {var originalMethod = descriptor.value;var newMethod = function(...args: any[]): any {var result: any = originalMethod.apply(this, args);if(!this.loggedOutput) {this.loggedOutput = new Array<any>();}this.loggedOutput.push({method: key,parameters: args,output: result,timestamp: new Date()});return result;};descriptor.value = newMethod; }class Calculator {@LogOutputdouble (num: number): number {return num * 2;} }let calc = new Calculator(); calc.double(11); // console ouput: [{method: "double", output: 22, ...}] console.log(calc.loggedOutput);

最后我們來看一下參數(shù)裝飾器:

TypeScript 參數(shù)裝飾器

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

declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number ) => void

參數(shù)裝飾器顧名思義,是用來裝飾函數(shù)參數(shù),它接收三個(gè)參數(shù):

  • target: Object - 被裝飾的類

  • propertyKey: string | symbol - 方法名

  • parameterIndex: number - 方法中參數(shù)的索引值

function Log(target: Function, key: string, parameterIndex: number) {var functionLogged = key || target.prototype.constructor.name;console.log(`The parameter in position ${parameterIndex} at ${functionLogged} hasbeen decorated`); }class Greeter {greeting: string;constructor(@Log phrase: string) {this.greeting = phrase; } } // console output: The parameter in position 0 at Greeter has // been decorated

我有話說

1.Object.defineProperty() 方法有什么用 ?

Object.defineProperty 用于在一個(gè)對(duì)象上定義一個(gè)新的屬性或者修改一個(gè)已存在的屬性,并返回這個(gè)對(duì)象。 方法的簽名:Object.defineProperty(obj, prop, descriptor) ,參數(shù)說明如下:

  • obj 需要定義的屬性對(duì)象

  • prop 需被定義或修改的屬性名

  • descriptor 需被定義或修改的屬性的描述符

對(duì)象里目前存在的屬性描述符有兩種主要形式:數(shù)據(jù)描述符和存取描述符。數(shù)據(jù)描述符是一個(gè)擁有可寫或不可寫值的屬性。存取描述符是由一對(duì) getter-setter 函數(shù)功能來描述的屬性。描述符必須是兩種形式之一,不能同時(shí)是兩者。

數(shù)據(jù)描述符和存取描述符均具有以下可選鍵值:

  • configurable
    當(dāng)且僅當(dāng)該屬性的 configurable 為 true 時(shí),該屬性才能夠被改變,也能夠被刪除。默認(rèn)為 false。

  • enumerable
    當(dāng)且僅當(dāng)該屬性的 enumerable 為 true 時(shí),該屬性才能夠出現(xiàn)在對(duì)象的枚舉屬性中。默認(rèn)為 false。

數(shù)據(jù)描述符同時(shí)具有以下可選鍵值:

  • value
    該屬性對(duì)應(yīng)的值??梢允侨魏斡行У?JavaScript 值(數(shù)值,對(duì)象,函數(shù)等)。默認(rèn)為 undefined。

  • writable
    當(dāng)且僅當(dāng)僅當(dāng)該屬性的writable為 true 時(shí),該屬性才能被賦值運(yùn)算符改變。默認(rèn)為 false。

存取描述符同時(shí)具有以下可選鍵值:

  • get
    一個(gè)給屬性提供 getter 的方法,如果沒有 getter 則為 undefined。該方法返回值被用作屬性值。默認(rèn)為undefined。

  • set
    一個(gè)給屬性提供 setter 的方法,如果沒有 setter 則為 undefined。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認(rèn)為undefined。

使用示例:

var o = {}; // 創(chuàng)建一個(gè)新對(duì)象 Object.defineProperty(o, "a", {value : 37, writable : true, enumerable : true, configurable : true});

總結(jié)

本文主要介紹了 TypeScript 中的四種裝飾器,了解裝飾器的基本分類和實(shí)現(xiàn)原理,為我們下一篇深入 Angular 2 的 @NgModule、@Component、@Injectable 等常用裝飾器做好鋪墊。

總結(jié)

以上是生活随笔為你收集整理的Angular 2 Decorators - 1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。