- 为对象添加新功能
- 不改变原有的结构
其实就是对类、组件的功能增强:
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实现
```javascript
function 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 = false
return desctiptor
}
4、log装饰器实现
function log(target, name, descriptor) {
const oldValue = descriptor.value
descriptor.value = function() {
console.log(`Calling ${name} with`, arguments)
oldValue.apply(this, arguments)
}
return descriptor
}
5、第三方库 core-decorators
- deprecate
6、验证
将现有的对象和装饰器进行分离,两者独立
符合开放封闭原则