- 为对象添加新功能
- 不改变原有的结构
其实就是对类、组件的功能增强:
class Circle {draw() {console.log('画圆形')}}class Decorator {constructor(circle) {this.circle = circle}draw() {this.circle.draw()this.bordered()}bordered() {console.log('话边框')}}let circle = new Circle()let newCirle = new Decorator(circle)newCircle.draw() // 增强了原有draw函数的功能,但是又没有改变原有类的功能
举例:
- ES7装饰器
- core-decorators
1、如果想使用ES7的装饰器功能,需要安装babel插件 babel-plugin-transform-decorators-legacy,然后配置babel.rc文件
{"presets": ["es2015", "latest"],"plugins": ["transform-decorators-legacy"]}
2、装饰器装饰类原理
- 装饰器传参
```javascript
function testDec(isDec) {
return function(target) { // target就是被装饰的对象
} }target.isDec = isDec
@testDec(true) // 装饰器可以传参数 class Demo{}
const demo = new Demo() console.log(demo.isDec) // true
- 模拟mixins实现```javascriptfunction mixins(...list) {return function (target) {Object.assign(target.prototype, ...list)}}const Obj1 = {fun1() {console.log('fun1')}}@mixins(Obj1) // 利用原型链扩展class TargetClass {}let obj = new TargetClass()obj.fun1() // fun1
3、readOnly实现
function readonly(target, name, descriptor) {// descriptor 属性描述对象 在object.defineProperty中经常用到,默认值如下// {// value: 'sepcifiedFunction', // 就是属性的值,默认 undefined// enumerable: false, // 决定 for in 或 Object.keys 能否枚举该属性// get: // 访问器函数(getter),函数或 undefined,在取属性值时被调用// set: // 设置器函数(setter),函数或 undefined,在设置属性值时被调用// configurable: true, // 决定该属性能否被删除,以及除 value 和 writable 外的其他特性是否可以被修改// writable: true // 决定属性能否被赋值// }descriptor.writable = falsereturn desctiptor}
4、log装饰器实现
function log(target, name, descriptor) {const oldValue = descriptor.valuedescriptor.value = function() {console.log(`Calling ${name} with`, arguments)oldValue.apply(this, arguments)}return descriptor}
5、第三方库 core-decorators
- deprecate
6、验证
将现有的对象和装饰器进行分离,两者独立
符合开放封闭原则
