如何在 TypeScript 中使用属性装饰器?
装饰器是一种用所需值和功能包装现有代码的方法,以创建它的新修改版本。目前,它仅支持一个类及其组件,如下所述:
- 类本身
- 类方法
- 类属性
- 类的对象访问器(Getter 和 Setter)
- 类方法的参数
注意:目前,装饰器处于 JavaScript 的第 2 阶段提案中,可作为 TypeScript 的实验性功能使用。要启用对装饰器的实验性支持,您必须在命令行或 tsconfig.json 中启用experimentalDecorators 编译器选项
句法:
@(argument)
// code of component ...
示例:举个例子,我们有一个 Greeter 类,它有两个属性 firstMessage 和 secondMessage,我们将登录到控制台。我们将使用装饰器通过添加参数中提供的发件人名称来修改 firstMessage 属性。请参阅下面的课程:
Javascript
class Greeter {
@ModifyMessage('gfg')
first_message: string;
second_message: string;
}
Javascript
function ModifyMessage(sender: string) {
return function (target: any, propertyKey: string) {
// use sender, target and propertyKey arguments ...
}
}
Javascript
function ModifyMessage(sender: string) {
return function (target: any, propertyKey: string) {
let modifiedMessage: string;
// Return modifiedMessage whenever the message is asked
const getter = function () {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function () {
modifiedMessage = `Hello from ${sender}!`;
};
}
}
Javascript
function ModifyMessage(sender: string)
return function (target: any, propertyKey: string) {
let modifiedMessage: string;
// Return modifiedMessage whenever the message is asked
const getter = function () {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function () {
modifiedMessage = `Hello from ${sender}!`;
};
// Overwrite the original message with
// modifiedMessage we just created
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
}
Javascript
function ModifyMessage(sender: string) {
return function(target: any, propertyKey: string) {
let modifiedMessage : string;
// Return modifiedMessage whenever the message is asked
const getter = function() {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function() {
modifiedMessage = `Hello from ${sender}!`;
};
// Overwrite the original message with
// modifiedMessage we just created
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
}
class Greeter {
// Modify message property using decorator
@ModifyMessage("gfg")
firstMessage: string;
secondMessage: string;
constructor() {
this.firstMessage = "Hi there!";
this.secondMessage = "Hi there!";
}
greet() {
console.log(`first message: ${this.firstMessage}`);
console.log(`second message: ${this.secondMessage}`);
}
}
let myGreeter = new Greeter();
myGreeter.greet();
在这里,我们为 Greeter 类的 firstMessage 属性使用了修饰器 ModifyMessage。它将在运行时使用提供的参数调用 ModifyMessage函数。它应该返回一个函数,在这个函数中我们可以使用 firstMessage 属性。请参阅下面的此函数:
Javascript
function ModifyMessage(sender: string) {
return function (target: any, propertyKey: string) {
// use sender, target and propertyKey arguments ...
}
}
我们返回的函数有两个参数:
- 目标:如果我们在静态成员上使用装饰器,则为类的构造函数;如果在实例成员上使用装饰器,则为类的原型。在我们的例子中,firstMessage 是一个实例成员,因此目标将引用 Greeter 类的原型。
- propertyKey:它是属性的名称。
让我们在 ModifyMessage函数。当我们想要获取 firstMessage 或将 firstMessage 设置为新值时,将触发这些函数。请看下面的代码:
Javascript
function ModifyMessage(sender: string) {
return function (target: any, propertyKey: string) {
let modifiedMessage: string;
// Return modifiedMessage whenever the message is asked
const getter = function () {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function () {
modifiedMessage = `Hello from ${sender}!`;
};
}
}
最后,我们将使用 Object.defineProperty函数。它用于将给定属性添加到对象。它需要三个参数:
- 对象实例:我们要为其添加属性的对象。在我们的例子中,Greeter Class 实例存储在目标变量中。
- propertyName:属性的名称
- 配置对象:它是一个具有属性规范的对象。在我们的例子中,我们将添加 getter 和 setter函数作为规范。
我们将使用这个函数用我们的 modifiedMessage 覆盖现有的 firstMessage 属性。请看下面的代码:
Javascript
function ModifyMessage(sender: string)
return function (target: any, propertyKey: string) {
let modifiedMessage: string;
// Return modifiedMessage whenever the message is asked
const getter = function () {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function () {
modifiedMessage = `Hello from ${sender}!`;
};
// Overwrite the original message with
// modifiedMessage we just created
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
}
现在我们准备好使用装饰器了。请参阅下面的完整代码:
Javascript
function ModifyMessage(sender: string) {
return function(target: any, propertyKey: string) {
let modifiedMessage : string;
// Return modifiedMessage whenever the message is asked
const getter = function() {
return modifiedMessage;
};
// Set the modifiedMessage value
const setter = function() {
modifiedMessage = `Hello from ${sender}!`;
};
// Overwrite the original message with
// modifiedMessage we just created
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter
});
}
}
class Greeter {
// Modify message property using decorator
@ModifyMessage("gfg")
firstMessage: string;
secondMessage: string;
constructor() {
this.firstMessage = "Hi there!";
this.secondMessage = "Hi there!";
}
greet() {
console.log(`first message: ${this.firstMessage}`);
console.log(`second message: ${this.secondMessage}`);
}
}
let myGreeter = new Greeter();
myGreeter.greet();
输出:
first message: Hello from gfg!
second message: Hi there!
结论:因此,我们看到我们可以在类的属性上使用装饰器并对其进行操作。装饰器帮助我们创建更具可读性和灵活性的代码。