昨天在看一个拖拽库的时候,遇到了这么一段代码,感觉很有意思:
1 2 3 4 5 6 7 8 9 10 11 12
| @sortable class DemoHOCItem extends React.Component {
render() { return ( <div { ...this.props }> { this.props.children } </div> ); } }
|
查了一下之后发现这是 es7 的新语法,叫 Decorator。
语法
如果要定义一个 Decorator 的话,不难,其实每一个 decorator 就是一个 function,有三个参数,像这样
1 2 3 4 5 6 7 8 9
| let log = (target, name, descriptor) => { console.log(target, name, descriptor);
const method = descriptor.value; descriptor.value = (...args) => { logger.info(`before function execute: ${name}(${args}) = ?`); return method.apply(target, args); } }
|
三个参数还是比较好理解的
然后要用这个 decorator 的时候
1 2 3 4 5 6 7 8 9 10 11
| class Example {
@log add(a, b) { return a + b; } }
let my = new Example(); my.add(2, 3);
|
这好像跟 Java 的 Annotation 形式差不多。 但是功能却跟 Python 的 Decorator 一样。
下面是运行时的输出

所以呢,decorator 的三个参数分别是
- target 目标方法所在的类
- name 方法名
- descriptor 该方法的一些描述, 其中
value 就是方法本身,这一点在上一个例子中已经看到了。
用在 class 上面
因为我最开始见到 decorator 是看到
1 2
| @sortable class DemoHOCItem extends React.Component {}
|
这时, decorator 是用在 class 上面的,当 decorator 用在 class 上面的时候只有第一个参数有值,比如
1 2 3 4
| @log class Example { add(a, b) { return a + b; } }
|
只会输出
1 2 3 4
| # 也就是 name, descriptor 都是 undefined 2016-12-21 10:28:26.617 function Example() { _classCallCheck(this, Example); } undefined undefined
|