装饰器模式
- 为对象添加新功能
- 不改变其原有的结构和功能
示例
class Circle {
draw() {
console.log("画一个圆形");
}
}
class Decorator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(circle);
}
setRedBorder(circle) {
console.log("设置红色边框");
}
}
const circle = new Circle();
circle.draw();
const dec = new Decorator(circle);
dec.draw();
场景
ES7 装饰器
安装 babel 插件
npm i -D babel-plugin-transform-decorators-legacy
配置.babelrc
- 验证配置
@testDec
class Demo {}
function testDec(target) {
target.isDec = true;
}
console.log(Demo.isDec);
- mixin
function mixin(...list) {
return function(target) {
Object.assign(target.prototype, ...list);
};
}
const Foo = {
foo() {
console.log("foo");
}
};
@mixin(Foo)
class MyClass {}
const obj = new MyClass();
obj.foo();
- 装饰方法
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}`;
}
}
// 测试
const p = new Person();
console.log(p.name());
p.name = 1; // 报错, name是只读的
function log(target, name, descriptor) {
const 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;
}
}
// 测试
const math = new Math();
console.log(math.add(2, 4));
core-decorators
- 第三方开源 lib
- 提供常用的装饰器
- 查阅 GitHub文档
设计原则验证
- 将现有对象和装饰器进行分离, 两者独立存在
- 符合开放封闭原则