打字稿装饰器不是唯一的问题
Typescript decorators not unique issues
我有以下情况,我想使用装饰器来基本上更改函数的获取,目标是获取 return 如果已设置或未设置特定变量。
我有执行此操作所需的代码,但我认为我不完全了解装饰器的工作原理。我在打字稿操场上创建了以下示例:here
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string | symbol // The name of the property
) {
let value = false;
console.log('hit');
return {
get: () => {
return value;
},
set: (val: string) => {
value = val.toLowerCase() !== 'false';
},
enumerable: true,
configurable: true
};
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
@PropertyDecorator
name2: string;
constructor() {
console.log('New instance');
console.log(this.name, 'should be false');
this.name = 'hey';
console.log(this.name, 'should be true');
console.log(this.name2, 'should be false');
}
}
new PropertyDecoratorExample();
new PropertyDecoratorExample();
有没有从例子中看出,对象的第一个实例是正确的(查看控制台)
但是,第二个实例由于某种原因与第一个实例保持相同的上下文,有什么想法吗?或者这里有什么问题?
问题是您的装饰器在每个 class 每个装饰字段只调用一次。因此,装饰器内的箭头函数将捕获 value
变量并将其用于装饰器 class 的所有实例。
你不应该将实例数据保存在装饰器函数变量中(因为如上所述它们将被共享)你可以将数据保存在当前实例上,如果你使用常规函数,则可以在内部访问 get/set 函数使用 this
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string // The name of the property
): any {
console.log('hit');
return {
get: function () {
return !!this[propertyKey + 'value'];
},
set: function(val: string) {
this[propertyKey + 'value'] = val.toLowerCase() !== 'false';
},
enumerable: true,
configurable: true
};
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
@PropertyDecorator
name2: string;
constructor() {
console.log('New instance');
console.log(this.name, 'should be false');
this.name = 'hey';
console.log(this.name, 'should be true');
console.log(this.name2, 'should be false');
}
}
new PropertyDecoratorExample();
new PropertyDecoratorExample();
我有以下情况,我想使用装饰器来基本上更改函数的获取,目标是获取 return 如果已设置或未设置特定变量。
我有执行此操作所需的代码,但我认为我不完全了解装饰器的工作原理。我在打字稿操场上创建了以下示例:here
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string | symbol // The name of the property
) {
let value = false;
console.log('hit');
return {
get: () => {
return value;
},
set: (val: string) => {
value = val.toLowerCase() !== 'false';
},
enumerable: true,
configurable: true
};
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
@PropertyDecorator
name2: string;
constructor() {
console.log('New instance');
console.log(this.name, 'should be false');
this.name = 'hey';
console.log(this.name, 'should be true');
console.log(this.name2, 'should be false');
}
}
new PropertyDecoratorExample();
new PropertyDecoratorExample();
有没有从例子中看出,对象的第一个实例是正确的(查看控制台) 但是,第二个实例由于某种原因与第一个实例保持相同的上下文,有什么想法吗?或者这里有什么问题?
问题是您的装饰器在每个 class 每个装饰字段只调用一次。因此,装饰器内的箭头函数将捕获 value
变量并将其用于装饰器 class 的所有实例。
你不应该将实例数据保存在装饰器函数变量中(因为如上所述它们将被共享)你可以将数据保存在当前实例上,如果你使用常规函数,则可以在内部访问 get/set 函数使用 this
function PropertyDecorator(
target: Object, // The prototype of the class
propertyKey: string // The name of the property
): any {
console.log('hit');
return {
get: function () {
return !!this[propertyKey + 'value'];
},
set: function(val: string) {
this[propertyKey + 'value'] = val.toLowerCase() !== 'false';
},
enumerable: true,
configurable: true
};
}
class PropertyDecoratorExample {
@PropertyDecorator
name: string;
@PropertyDecorator
name2: string;
constructor() {
console.log('New instance');
console.log(this.name, 'should be false');
this.name = 'hey';
console.log(this.name, 'should be true');
console.log(this.name2, 'should be false');
}
}
new PropertyDecoratorExample();
new PropertyDecoratorExample();