From 66da3530bf1b89d90c8ae467553ad9769bffee7d Mon Sep 17 00:00:00 2001 From: liuyi Date: Sun, 11 May 2025 21:35:09 +0800 Subject: [PATCH] decorator demo --- src/example/exp1.ts | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/example/exp2.ts | 33 +++++++++++++++++++++++++++++++++ src/example/exp3.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 src/example/exp1.ts create mode 100644 src/example/exp2.ts create mode 100644 src/example/exp3.ts diff --git a/src/example/exp1.ts b/src/example/exp1.ts new file mode 100644 index 0000000..29d4503 --- /dev/null +++ b/src/example/exp1.ts @@ -0,0 +1,44 @@ +type DecoratorFunc = (target: any, key: string, descriptor: PropertyDescriptor) => void; + +const createDecorator = (decorator: DecoratorFunc) => (Model: any, key: string) => { + const target = Model.prototype; + const descriptor = Object.getOwnPropertyDescriptor(target, key); + decorator(target, key, descriptor); +}; + +const logger: DecoratorFunc = (target, key, descriptor) => + Object.defineProperty(target, key, { + ...descriptor, + value: async (...args: any[]) => { + try { + return descriptor.value.apply(this, args); + } finally { + const now = new Date().valueOf(); + console.log(`lasted logged in ${now}`); + } + }, + }); + +class User { + async login() { + console.log('login success'); + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); + } +} + +export const exp1 = () => { + console.log(); + console.log( + '-----------------------示例1:高阶函数柯里化(装饰器内部原理)-----------------------', + ); + console.log('-----------------------实现登录和日志记录解耦-----------------------'); + console.log(); + const loggerDecorator = createDecorator(logger); + loggerDecorator(User, 'login'); + const user = new User(); + user.login(); + console.log(); + console.log('-----------------------示例1:执行完毕-----------------------'); +}; diff --git a/src/example/exp2.ts b/src/example/exp2.ts new file mode 100644 index 0000000..08faa2a --- /dev/null +++ b/src/example/exp2.ts @@ -0,0 +1,33 @@ +const HelloDecorator = any>(constructor: T) => { + return class extends constructor { + newProperty = 'new property'; + hello = 'override'; + + sayHello() { + return this.hello; + } + }; +}; + +@HelloDecorator +export class Hello { + [key: string]: any; + + hello: string; + + constructor() { + this.hello = 'test'; + } +} + +export const exp2 = () => { + console.log('-----------------------示例2:简单的类装饰器-----------------------'); + console.log( + '-----------------------动态添加一个sayHello方法以及覆盖hello的值-----------------------', + ); + console.log(); + const hello = new Hello(); + console.log(hello.sayHello()); + console.log(); + console.log('-----------------------示例2:执行完毕-----------------------'); +}; diff --git a/src/example/exp3.ts b/src/example/exp3.ts new file mode 100644 index 0000000..05eb58d --- /dev/null +++ b/src/example/exp3.ts @@ -0,0 +1,30 @@ +const SetNameDecorator = (firstName: string, lastName: string) => { + const name = `${firstName}.${lastName}`; + return any>(target: T) => { + return class extends target { + _name: string = name; + + getMyName() { + return this._name; + } + }; + }; +}; + +@SetNameDecorator('ray', 'liuyi') +class UserService { + [key: string]: any; + + c() {} +} + +export const exp3 = () => { + console.log(); + console.log('-----------------------示例3:装饰器工厂-----------------------'); + console.log('-----------------------通过继承方式 重载getName方法-----------------------'); + console.log(); + const user = new UserService(); + console.log(user.getMyName()); + console.log(); + console.log('-----------------------示例3:执行完毕-----------------------'); +};