SyntaxError: a.js: Decorators are not officially supported yet in 6.x pending a proposal update.
However, if you need to use them you can install the legacy decorators transform with:
npm install babel-plugin-transform-decorators-legacy --save-dev
and add the following line to your .babelrc file:
{
"plugins": ["transform-decorators-legacy"]
}
{
The repo url is: https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy.
前言
如果曾经使用过 Python,尤其是 Django 的话,应该对 装饰器 的概念有些许的了解。在函数前加
@user_login
这样的语句就能判断出用户是否登录。装饰器可以说是解决了不同类之间共享方法的问题(可以看做是弥补继承的不足)。
这句话可以说是对装饰器的非常漂亮的解释。
在未来的 JavaScript 中也引入了这个概念,并且 babel 对他有很好的支持。如果你是一个疯狂的开发者,就可以借助 babel 大胆使用它。
正文
工具准备
装饰器目前在浏览器或者 Node 中都暂时不支持,需要借助 babel 转化为可支持的版本
安装 babel
按照官网的 说明 安装:
在
.babelrc
中写入:安装 decorators 插件
如果不装插件执行
babel-node a.js
或者babel a.js > b.js
的话都会提示:按照说明,安装 babel-plugin-transform-decorators-legacy 插件:
.babelrc :
这样准备工作就完成了。
正式开始
装饰 类的方法
装饰器接收三个参数,这三个参数和 Object.defineProperty() 基本保持一致,分别表示:
再看上面的代码:
Man {}
这个类init()
Object.defineProperty()
一样:{value: [Function], writable: true, enumerable: false, configurable: true}
descriptor.value = (...args)=>
中的 args 是一个数组,分别对应 def、atk、hp,给 def + 100,然后再执行method
(即被装饰的函数),最后返回descriptor
。这样就给
init
函数包装了一层。带参数装饰 类的方法
有时候,需要给装饰器传参数:
装饰 类
上面两个装饰器都是对类里面的函数进行装饰,改变了类的静态属性;除此之外,还可以对类进行装饰,给类添加方法或者修改方法(通过被装饰类的 prototype):
装饰 普通函数
不建议装饰,因为变量提升会产生系列问题
衍生
装饰器的使用场景基本都是 AOP。大多数日志场景都可以使用此种模式,比如这里一个简单的 日志场景。
对于纯前端来说,也有很多用途,比如实现一个 react 的 lazyload,就可以使用装饰器修饰整个 class。
同时,也有一些库实现了常用的装饰器,比如:core-decorators.js
参考文章