我正在学习 Typescript 中用于 Angular 2+ 的装饰器。我知道装饰器只是函数。
我发现有时装饰器必须返回一个函数,有时逻辑在装饰器函数内执行而没有任何返回。
考虑类装饰器
@course
class Person {
constructor() {
console.log("Test")
}
}
装饰器类(class)定义如下。它定义了 Person.prototype 的一些属性。它什么也不返回。
function course(target) {
Object.defineProperty(target.prototype, 'course', {value: () => "Angular 2"})
}
鉴于:
@course{
course:"Sample_decorator"
}
class Person {
constructor() {
console.log("Test")
}
}
装饰器类(class)定义如下。它返回一个函数。
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"
那么它怎么会自动调用返回函数呢?
最佳答案
根据spec proposal你可以有两种类型的装饰器:
- 成员装饰器函数
A member decorator function is a function which takes a member descriptor and which returns a member descriptor
- 类装饰器函数
A class decorator function is a function which takes a constructor, heritage (parent class), and an array of MemberDescriptors that represent the instance and static members of the class.
您还可以拥有多个链式装饰器。如果是这种情况,装饰器返回的值将成为下一个装饰器的输入。
所以,装饰器函数应该这样使用:
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
另请阅读:
关于JavaScript/ typescript : should decorator return a function,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46872252/