Javascript / Typescript:应该装饰器返回一个函数

时间:2017-10-22 08:59:10

标签: javascript angular typescript decorator

我正在学习在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"

那么它如何自动调用返回函数。

1 个答案:

答案 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

同时阅读: