【问题标题】:Javascript/Typescript: should decorator return a functionJavascript/Typescript:装饰器应该返回一个函数
【发布时间】:2018-04-02 23:48:13
【问题描述】:

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

那么它怎么会自动调用返回函数呢。

【问题讨论】:

  • 装饰器由于在 Angular 2+ 中的使用而变得流行。在 Angular 中,通过 TypeScript 可以使用装饰器,但在 JavaScript 中,它们目前是第 2 阶段的提案,这意味着它们应该成为该语言未来更新的一部分。 sitepoint.com/javascript-decorators-what-they-are
  • Angular 4 中使用的打字稿

标签: javascript angular typescript decorator


【解决方案1】:

根据spec proposal,你可以有两种类型的装饰器:

  • 成员装饰器函数

成员装饰器函数是一个接受成员的函数 描述符并返回一个成员描述符

  • 类装饰器函数

类装饰器函数是一个带有构造函数的函数, 遗产(父类),以及一个成员描述符数组 表示类的实例和静态成员。

你也可以有多个链式装饰器。如果是这种情况,装饰器返回的值将成为下一个装饰器的输入。

所以,装饰器函数应该是这样使用的:

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

另请阅读:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 2020-12-04
    • 2016-10-20
    相关资源
    最近更新 更多