装饰器模式
装饰器模式,又名装饰者模式。它的定义是“在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用户的更复杂需求”
介绍
为对象添加新功能
不改变七原有的结构和功能
示例
代码演示
class Circle {
draw() {
console.log('画一个圆形');
}
}
class Decorator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(circle);
}
setRedBorder(circle) {
console.log('设置红色边框');
}
}
let circle = new Circle();
circle.draw();
let dec = new Decorator(circle);
dec.draw();
场景
ES7 装饰器
core-decorators
ES7 装饰器
配置环境
下载插件
babel-plugin-transform-decorators-legacy
@testDec
class Demo {}
function testDec(target) {
target.isDec = true;
}
alert(Demo.isDec); // true
装饰器语法
class Cat {
say() {
console.log('meow ~');
}
}
上面这段代码是 ES6 中定义一个类的写法,其实只是一个语法糖,而实际上当我们给一个类添加一个属性的时候,会调用到 Object.defineProperty
这个方法,它会接受三个参数:target
、name
和 descriptor
,所以上面的代码实际上在执行时是这样的:
function Cat() {}
Object.defineProperty(Cat.prototype, 'say', {
value: function () {
console.log('meow ~');
},
enumerable: false,
configurable: true,
writable: true,
});
装饰方法
例子 1
function readonly(target, name, descriptor) {
descriptor.writable = false; // 不能修改
return descriptor;
}
class Person {
constructor() {
this.first = 'A';
this.last = 'B';
}
@readonly
name() {
return `${this.first} ${this.last}`;
}
}
let p = new Person();
console.log(p.name()); // 能读
p.name = function () {
alert(100); // 不能写
};
例子 2
function log(target, name, descriptor) {
let oldValue = descriptor.value;
descriptor.value = function () {
console.log(`calling ${name} with`, arguments);
return oldValue.apply(this, arguments);
};
return descriptor;
}
class Math {
@log
add(a, b) {
return a + b;
}
}
let math = new Math();
const result = math.add(2, 4);
console.log('result', result);
core-decorators
第三方库
好用
设计原则
将现有对象和装饰器进行分离,两者独立存在
符合开发封闭原则