函数装饰器

63

我看到babel.js修饰器(在“阶段1”中可用)实现了https://github.com/wycats/javascript-decorators上的规范。看起来修饰器只限于(1)类,(2)访问器和(3)方法。在我的情况下,我想在普通的函数上使用装饰器,就像这样:

@chainable
function foo() { }

其中(仅为例子)

function chainable(fn) {
  return function() {
    fn.apply(this, arguments);
    return this;
  };
}

我不认为有任何逻辑上的理由说明为什么修饰器不能应用于函数。我的问题是,是否有某种方法可以实现这一点?或者,是否有某些很好的原因说明函数不能被装饰?

事实证明,在https://github.com/wycats/javascript-decorators/issues/4上提出了这个问题。

3个回答

36

运行装饰器时,您需要评估一个表达式,并且这样做会防止提升(即使是变量声明,赋值操作的右侧也会保持不变)。因此,它与函数声明提升不兼容。

作为解决方法,我建议启用可以进行装饰的函数表达式、生成器函数表达式和箭头函数:

const func = @someDecorator('abc') (x, y) => { return x + y };

唉,那并没有得到太多的热情反应:函数修饰器


1
为什么不直接写 const func = someDecorator('abc')((x, y) => { return x + y });,而非 const func = @someDecorator('abc') (x, y) => { return x + y };?在我看来,在这种情况下,那个微小的额外语法并没有给你带来任何好处。 - Ajedi32
2
对于你在有关函数装饰时如何防止提升的线程中的第一个建议,点个赞 :) - Hrishi
3
当有多个装饰器时,使用第一种方式更易于阅读。比较一下 decorator1('abc')(decorator2('def')(decorator3('ghi')((x, y) => ...)))@decorator1('abc') @decorator2('def') @decorator3('ghi') (x, y) => ... 两种方式。实际上,将第一种写法输完花费的时间比应该花费的时间还要长,因为需要确保括号配对正确。 - Andy E
哇,如果Rauschmayer博士在SO上回答我的问题,我会感到非常激动。:D - Jeff McMahan

8

1
我认为问题在于函数装饰器尚未被ES7草案所涵盖。 当然,您仍然可以自己实现函数装饰器。

通过实现它自己,您的意思是编写自己的解析器/转译器吗? - user663031
2
@torazaburo 不,你可以编写一个 Babel 插件。 - Neo Ko
1
https://github.com/ukari/javascript-let-decorators有人已经完成了这个项目,很多人都在询问此功能,但似乎没有合适的Babel插件。 - AviKKi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接