25

我看到今天已经在一些 javascript 代码中使用了装饰器。我的问题实际上是两个方面。

第一的:

如果装饰器还没有最终确定,那么今天如何在生产代码中使用它们呢?浏览器支持会不存在吗?

第二:

鉴于今天可以使用它,正如一些开源项目所建议的那样,让装饰器工作的典型推荐设置是什么?

4

3 回答 3

20

没错,ES2016 装饰器还不是规范的一部分。但这并不意味着我们今天不能使用它。

首先让我们退后一步,回顾一下“什么是装饰器”。装饰器只是将行为添加到对象的包装器。这不是javascript(或一般编程)中的新概念,它实际上已经存在了一段时间......

这是检查权限的装饰器的基本示例:

function AuthorizationDecorator(protectedFunction) {
    return function() {
        if (user.isTrusted()) {
            protectedFunction();
        } else {
            console.log('Hey! No cheating!');
        }
    }
}

使用它看起来像这样:

AuthorizationDecorator(save);

你看我们所做的只是简单地包装一些其他的功能。您甚至可以通过多个装饰器传递一个函数,每个装饰器添加一个功能或运行一些代码。

您甚至可以找到一些解释 javascript 中装饰器模式的旧文章。

既然我们了解装饰器实际上是我们(javascript 社区)一直能够做到的事情,那么当我们今天使用 ES2016 装饰器时,它们只是被编译成 ES5 代码,因此您保持浏览器兼容性可能并不令人震惊。所以暂时它只是语法糖(我可能会添加一些非常甜的糖)。

至于使用哪个编译器将您的 ES2016 代码转换为 ES5 代码,您有一些选择:BabelTraceur是最流行的。

这是关于探索 ES2016 装饰器的进一步阅读。

于 2015-12-25T10:06:33.930 回答
5

@Class可以在 Babel/Traceur 中启用装饰器支持

通天塔:

$ babel --optional es7.decorators

资料来源:展示 ES7 装饰器 - 中

示踪剂:

traceurOptions: {
  "annotations": true
}

@Property不支持装饰器

...并且由于每个都@Property提供了独特的功能,因此每个都需要在 ES6/7 中使用不同的方法来脱糖。

以下是您的使用方法@Inject

打字稿

exports class ExampleComponent {
  constructor(@Inject(Http) http: Http) {
    this.http = http;
  }
}

ES 6/7

exports class ExampleComponent {
  constructor(http) {
    this.http = http;
  }

  static get parameters() {
    return [[Http]];
  }
}

来源:https ://stackoverflow.com/a/34546344/290340

更新:

看起来 Babel 改变了装饰器的配置方式,文章已经过时了。这是新方法的链接。

简而言之; @Class的,你可以在 ES6/7中使用装饰器;ES6/7 不支持任何属性装饰器,因此您必须使用变通方法。

于 2015-12-31T13:57:52.537 回答
4

有一些使用装饰器的解决方案:

  • babel - 支持装饰器的 es5 编译器旁边的 es。
  • traceur - 谷歌 es5 编译器旁边的另一个 es。
  • typescript - 支持装饰器的 javascript 语言的类型化超集。

这些工具如何将“现代” javascript 转换为较旧的 javascript 存在一些差异,因此您可以在需要时探索它,因为它们有在线游乐场。

于 2015-12-25T10:08:36.600 回答