Tailwind CSSTailwind CSS
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
Home
  • Tailwind CSS 书籍目录
  • Vue 3 开发实战指南
  • React 和 Next.js 学习
  • TypeScript
  • React开发框架书籍大纲
  • Shadcn学习大纲
  • Swift 编程语言:从入门到进阶
  • SwiftUI 学习指南
  • 函数式编程大纲
  • Swift 异步编程语言
  • Swift 协议化编程
  • SwiftUI MVVM 开发模式
  • SwiftUI 图表开发书籍
  • SwiftData
  • ArkTS编程语言:从入门到精通
  • 仓颉编程语言:从入门到精通
  • 鸿蒙手机客户端开发实战
  • WPF书籍
  • C#开发书籍
learn
  • Java编程语言
  • Kotlin 编程入门与实战
  • /python/outline.html
  • AI Agent
  • MCP (Model Context Protocol) 应用指南
  • 深度学习
  • 深度学习
  • 强化学习: 理论与实践
  • 扩散模型书籍
  • Agentic AI for Everyone
langchain
  • 第9章:装饰器

第9章:装饰器

类装饰器、方法装饰器、属性装饰器

装饰器(Decorator)是 TypeScript 中一种特殊的声明,它可以附加到类、方法、属性或参数上,用于修改或扩展其行为。装饰器通过 @expression 的语法形式应用,其中 expression 必须是一个函数,它会在运行时被调用,并接收特定的参数。本节将详细介绍类装饰器、方法装饰器和属性装饰器的用法和实现原理。


类装饰器(Class Decorator)

类装饰器应用于类的构造函数,用于观察、修改或替换类定义。它接收一个参数:类的构造函数。

基本语法

function classDecorator(constructor: Function) {
    // 修改或扩展类
}

@classDecorator
class MyClass {}

示例:添加元数据

function logClass(target: Function) {
    console.log(`Class ${target.name} is decorated.`);
}

@logClass
class Person {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
}
// 输出:Class Person is decorated.

示例:修改类

类装饰器可以返回一个新的构造函数来替换原始类:

function extendClass<T extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor {
        newProperty = "New Property";
    };
}

@extendClass
class Animal {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
}

const cat = new Animal("Cat");
console.log((cat as any).newProperty); // 输出:New Property

方法装饰器(Method Decorator)

方法装饰器应用于类的方法,用于修改或观察方法的定义。它接收三个参数:

  1. 类的原型(或构造函数静态方法)。
  2. 方法名称。
  3. 方法的属性描述符(PropertyDescriptor)。

基本语法

function methodDecorator(
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
) {
    // 修改方法行为
}

class MyClass {
    @methodDecorator
    myMethod() {}
}

示例:日志装饰器

function logMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {
        console.log(`Calling ${propertyKey} with args: ${JSON.stringify(args)}`);
        return originalMethod.apply(this, args);
    };
}

class Calculator {
    @logMethod
    add(a: number, b: number) {
        return a + b;
    }
}

const calc = new Calculator();
calc.add(2, 3); // 输出:Calling add with args: [2,3]

示例:拦截方法调用

function delay(ms: number) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = function (...args: any[]) {
            setTimeout(() => {
                originalMethod.apply(this, args);
            }, ms);
        };
    };
}

class Greeter {
    @delay(1000)
    greet(name: string) {
        console.log(`Hello, ${name}!`);
    }
}

const greeter = new Greeter();
greeter.greet("Alice"); // 1秒后输出:Hello, Alice!

属性装饰器(Property Decorator)

属性装饰器应用于类的属性,用于观察或修改属性的行为。它接收两个参数:

  1. 类的原型(或构造函数静态属性)。
  2. 属性名称。

基本语法

function propertyDecorator(target: any, propertyKey: string) {
    // 修改或观察属性
}

class MyClass {
    @propertyDecorator
    myProperty: string;
}

示例:属性只读装饰器

function readOnly(target: any, propertyKey: string) {
    Object.defineProperty(target, propertyKey, {
        writable: false,
    });
}

class User {
    @readOnly
    id: number;
    constructor(id: number) {
        this.id = id;
    }
}

const user = new User(1);
user.id = 2; // 报错:Cannot assign to 'id' because it is read-only.

示例:属性监听

function watchProperty(target: any, propertyKey: string) {
    let value = target[propertyKey];
    Object.defineProperty(target, propertyKey, {
        get: () => value,
        set: (newValue) => {
            console.log(`Property ${propertyKey} changed from ${value} to ${newValue}`);
            value = newValue;
        },
    });
}

class Product {
    @watchProperty
    price: number;
    constructor(price: number) {
        this.price = price;
    }
}

const product = new Product(100);
product.price = 200; // 输出:Property price changed from 100 to 200

总结

  • 类装饰器:用于修改或替换类定义,接收构造函数作为参数。
  • 方法装饰器:用于修改方法行为,接收目标对象、方法名和属性描述符。
  • 属性装饰器:用于观察或修改属性,接收目标对象和属性名。

装饰器为 TypeScript 提供了强大的元编程能力,广泛应用于框架(如 Angular、NestJS)和工具库中。在下一节中,我们将学习如何通过装饰器工厂进一步定制装饰器的行为。

Last Updated:: 3/27/25, 10:50 AM