TypeScript 装饰器详解

还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。

No.内容链接
1Openlayers 【入门教程】 - 【源代码+示例300+】
2Leaflet 【入门教程】 - 【源代码+图文示例 150+】
3Cesium 【入门教程】 - 【源代码+图文示例200+】
4MapboxGL【入门教程】 - 【源代码+图文示例150+】
5前端就业宝典 【面试题+详细答案 1000+】

在这里插入图片描述


TypeScript 支持装饰器(Decorators),这是一种特殊类型的声明,可以被附加到类声明、方法、访问器、属性或参数上。装饰器使用 @expression 这种形式,expression 求值后必须为一个函数,该函数会在运行时被调用,被装饰的声明信息作为参数传入。

装饰器是实验性的功能,并且需要在编译时启用。要启用装饰器支持,你需要在你的 tsconfig.json 文件中设置 "experimentalDecorators": true

下面是一些装饰器的基本示例:

1. 类装饰器

类装饰器可以用来修改类的行为或者记录类的创建等。

function logClass(target: Function) {
    console.log(`Logging class ${target.name}`);
}

@logClass
class Greeter {
    greet() {
        console.log("Hello!");
    }
}

2. 属性装饰器

属性装饰器可以用来观察、修改或者替换类属性的定义。

function configurable(value: boolean) {
    return function (target: any, key: string) {
        let descriptor = Reflect.getOwnPropertyDescriptor(target, key);
        descriptor.configurable = value;
        Reflect.defineProperty(target, key, descriptor);
    };
}

class Example {
    @configurable(false)
    name = "Example";
}

let example = new Example();
// 以下操作会抛出错误,因为 name 已经被设置为不可配置
delete example.name; // TypeError: Cannot delete property 'name' of #<Example>

3. 方法装饰器

方法装饰器可以用来修改类的方法。

function enumerable(value: boolean) {
    return function (target: any, key: string, descriptor: PropertyDescriptor) {
        descriptor.enumerable = value;
    };
}

class Example {
    @enumerable(false)
    sayHello() {
        console.log("Hello!");
    }
}

let example = new Example();
for (let key in example) {
    console.log(key); // 不会输出 "sayHello" 因为它是不可枚举的
}

4. 参数装饰器

参数装饰器可以用来修改类方法的参数。

function required(target: any, methodName: string, parameterIndex: number) {
    const originalMethod = target[methodName];

    target[methodName] = function (...args: any[]) {
        if (args[parameterIndex] === undefined) {
            throw new Error('Parameter is required');
        }
        return originalMethod.apply(this, args);
    };
}

class Example {
    @required
    greet(@required message: string) {
        console.log(message);
    }
}

let example = new Example();
example.greet(); // 抛出错误 "Parameter is required"
example.greet("Hello!"); // 正常输出 "Hello!"

5. 复合装饰器

你可以在同一个声明上使用多个装饰器。

function log(target: any, key: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = function (...args: any[]) {
        console.log(`Calling "${key}" with`, args);
        return originalMethod.apply(this, args);
    };

    return descriptor;
}

class Example {
    @log
    doSomething(something: string) {
        console.log(`Doing something ${something}`);
    }
}

let example = new Example();
example.doSomething("important"); // 输出: Calling "doSomething" with ["important"]

以上示例展示了不同类型的装饰器及其使用方法。需要注意的是,装饰器的执行顺序是由它们在代码中的出现顺序决定的。如果一个声明上有多个装饰器,那么最接近声明体的那个装饰器会先执行。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还是大剑师兰特

打赏一杯可口可乐

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值