ES.next 直接调用或作为工厂函数调用的装饰器

ES.next decorators that get called either directly or as a factory function

我查看了 ES.next 装饰器的一些示例,并注意到可以制作一个装饰器,该装饰器可以作为带参数的因子函数应用,或者直接通过省略 () 同时结束。

我设法让任一样式单独工作,作为工厂函数 @decorate(withArgs),或直接 @decorate,但不能同时工作!

举个例子: https://github.com/jayphelps/core-decorators.js#deprecate-alias-deprecated

class foo {

  @deprecate
  foo() {}

  @deprecate("with an optional string")
  bar() {}
}

我试图检查上面提到的源代码,但由于我对装饰器的经验有限,我不知道如何设置类似的东西。


下面是我如何在不使用任何参数的情况下@decorate工作的

function decorate(target, key, descriptor) {
  // do some stuff and then return the new descriptor
}

下面是我如何设法让 @decorate(args) 将参数作为工厂函数使用:

function decorate(...args) {
  return function(target, key, descriptor) {
    // do some stuff using args and then return the new descriptor
  }
}

如您所见,此时它是 decorate foo()decorate(args) foo(),而不是两者。

当写 @decorator 时,浏览器期望 立即调用装饰函数 ,而当写 @decorator(args) 时,它期望 首先调用一个工厂,它将return一个装饰函数

这是我编写的一个装饰器示例,它将状态 属性 添加到 class 由 redux

驱动
export default function state (defaultState) {

    function reducer(state, action) {
        if (!state) {
            state = defaultState;
        }
        ...
    }

    function decorator (target) {...}

    // If 1st argument is a function, it means `@state` was written
    if (typeof defaultState === 'function') {
        let target = defaultState;
        defaultState = {};
        return decorator(target);
    } else {
        return decorator;
    }
}

Do note, that the decorator in the example is a class decorator, which has a different signature (target) than the method decorator you are writing (target, key, descriptor)

装饰器可以带参数也可以不带参数

import state from './decorators/redux-state'

@state({
    name: '',
})
class MyClass {
    ...
}

@state
class MyOtherClass {
    constructor(state= {name: ''}) {
        this.state = state;
    }
    ...
}

Jay Phelps 正在抽象弄清楚如何在 decorate 实用函数中调用装饰器的逻辑,这使得他的代码更难理解。

希望对您有所帮助