还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。
No. | 内容链接 |
---|---|
1 | Openlayers 【入门教程】 - 【源代码+示例300+】 |
2 | Leaflet 【入门教程】 - 【源代码+图文示例 150+】 |
3 | Cesium 【入门教程】 - 【源代码+图文示例200+】 |
4 | MapboxGL【入门教程】 - 【源代码+图文示例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"]
以上示例展示了不同类型的装饰器及其使用方法。需要注意的是,装饰器的执行顺序是由它们在代码中的出现顺序决定的。如果一个声明上有多个装饰器,那么最接近声明体的那个装饰器会先执行。