准备写这篇博客,是因为年初在找工作的时候,面试被问到了装饰器,对于ES6的好多新特性和方法还一知半解的我来说太超纲了!因此决定好好研究一下这是个啥[捂脸]~
1、概念
装饰器是ES7的语法,本质是一个wrapper,可以动态增强类以及实例方法,同时,被装饰者对于装饰者是无感知的。
2、使用
1)示例1,给类添加装饰器:
1 |
|
等同于
1 |
|
上面代码中,@testable就是一个装饰器,它修改了MyTestableClass这个类的行为,为其添加了属性isTestable。
上述只是个简单的例子,装饰器一般接受三个参数:
function(target, key, descriptor)
-
target: 需要定义属性的对象(MyTestableClass)
-
key: 需要定义或修改的属性的名字
-
descriptor: 将被定义或修改的属性的描述符(属性的描述对象)
这里可以看出其参数同Object.defineProperty是一样的,本质上来说,作用在类上的装饰器是通过Object.defineProperty来进行扩展和封装的。
2)示例2,给类的属性添加装饰器:
1 |
|
从上面例子可以看出,当装饰器作用域类本身的时候,我们操作的对象也是类本身,而当装饰器作用域某个具体的属性的时候,我们操作的对象既不是类本身,也不是类的属性,而是他的描述符,而描述符里记录着我们对这个属性的全部信息,所以,我们可以对它自由的进行扩展和封装。
3)装饰器特性:
- 有多个装饰器时,先从外到内进入,再由内向外执行。
1 |
|
上述代码中,dec装饰器又返回了一个装饰器,根据其特性,外层装饰器@dec(1)先进入,但是内层装饰器@dec(2)先执行。
- 装饰器不能用于普通函数,因为普通函数存在变量提升。
3、装饰器集合
core-decorators.js中内置了很多装饰器,可以根据实际情况使用。
1 |
|
以上是一个绑定原始对象的装饰器,还有:
- readonly:使属性或方法不可写;
- override:检查子类是否覆盖父类的同名方法;
- deprecate:在控制台显示一条警告,表示该方法将废除;
- suppressWarnings:抑制deprecated装饰器导致的console.warn()调用。但是,异步代码发出的调用除外;
- ……
4、编译装饰器
1 |
|
.babelrc文件如下:
1 |
|
参考文档: ES6入门-装饰器