首页 前端知识 TypeScript 装饰器详解

TypeScript 装饰器详解

2024-08-18 22:08:39 前端知识 前端哥 344 784 我要收藏

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

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

在这里插入图片描述

文章目录

      • 1. 类装饰器
      • 2. 属性装饰器
      • 3. 方法装饰器
      • 4. 参数装饰器
      • 5. 复合装饰器


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"]

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

转载请注明出处或者链接地址:https://www.qianduange.cn//article/16064.html
标签
评论
发布的文章

无涯教程-HTML5 - MathML

2024-08-25 23:08:46

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!