我正在学习在Angleular 2+中使用的Typescript中的装饰器。我知道装饰器只是功能。
我发现有时装饰器必须返回一个函数,有时逻辑是在装饰器函数内执行的,没有任何东西可以返回。
考虑类装饰器
@course
class Person {
constructor() {
console.log("Test")
}
}
装饰师课程定义如下。它定义了Person.prototype的一些属性。它什么都不返回。
function course(target) {
Object.defineProperty(target.prototype, 'course', {value: () => "Angular 2"})
}
鉴于:
@course{
course:"Sample_decorator"
}
class Person {
constructor() {
console.log("Test")
}
}
装饰师课程定义如下。它返回一个函数。
function course(config) {
return function (target) {
Object.defineProperty(
target.prototype,
'course',
{value: () => config.course,
writable: true,
enumerable: true,
configurable: true
} // 2
)
}
}
我无法理解自动调用返回函数的方式。因为它涉及两次调用。
如果我手动调用上述功能:
说
test = {
course:"Sample_decorator_testing"
}
首先调用装饰器函数:
var decor = course(test)
返回一个必须再次调用以运行defineproperty的函数。所以
decor(Person)
然后只有
sample = new Person
sample.course() \\ outputs "Sample_decorator_testing"
那么它如何自动调用返回函数。
答案 0 :(得分:1)
根据spec proposal,你可以有两种类型的装饰器:
成员装饰器功能是一个带成员的功能 描述符和返回成员描述符
类装饰器函数是一个带构造函数的函数, 遗产(父类),以及一个MemberDescriptors数组 表示类的实例和静态成员。
您还可以拥有多个链式装饰器。如果是这种情况,装饰器返回的值将成为下一个装饰器的输入。
因此,装饰器函数应该像这样使用:
class Person {
@deprecate
facepalm() {}
有趣的是,@
应该跟表达后面评估到decorator
函数。这意味着您可以使用将返回装饰器函数的@
符号后面的函数:
class Person {
@deprecate('We stopped facepalming')
facepalmHard() {}
在这种情况下,装饰器将如下实现:
function deprecate(descriptor) {
return deprecateDecoratorFunction(class, descriptorName, descriptor) {
根据提案,以下语法是正确的:
@decoratorFunction // IdentifierReference
@customObject.decoratorFunction // IdentifierReference . IdentifierName
@decoratorFunction(...) // IdentifierReference Arguments
@customObject.decoratorFunction(...) // IdentifierReference . IdentifierName Arguments
同时阅读: