装饰器模式 
装饰器模式,又名装饰者模式。它的定义是“在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用户的更复杂需求”
介绍 
为对象添加新功能
不改变七原有的结构和功能
示例 

代码演示 
javascript
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
javascript
@testDec
class Demo {}
function testDec(target) {
    target.isDec = true;
}
alert(Demo.isDec); // true装饰器语法 
javascript
class Cat {
    say() {
        console.log('meow ~');
    }
}上面这段代码是 ES6 中定义一个类的写法,其实只是一个语法糖,而实际上当我们给一个类添加一个属性的时候,会调用到 Object.defineProperty 这个方法,它会接受三个参数:target 、name 和 descriptor ,所以上面的代码实际上在执行时是这样的:
javascript
function Cat() {}
Object.defineProperty(Cat.prototype, 'say', {
    value: function () {
        console.log('meow ~');
    },
    enumerable: false,
    configurable: true,
    writable: true,
});装饰方法 
例子 1
javascript
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
javascript
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 
第三方库
好用
设计原则
将现有对象和装饰器进行分离,两者独立存在
符合开发封闭原则

