在不改变其原有的结构和功能下为对象添加新功能。
举例一:
class Circle {
constructor(name) {
this.name = name;
}
draw() {
console.log(`图的形状:${this.name}`);
}
}
class Decorator {
constructor(color, circle) {
this.color = color;
this.circle = circle;
}
draw() {
console.log(`绘制形状:${this.circle.name}`);
this.setBorder();
}
setBorder() {
console.log(`设置形状${this.color}边框`);
}
}
let circle1 = new Circle('圆');
let dec = new Decorator('红色', circle1);
circle1.draw();
dec.draw();
// 图的形状:圆
// 绘制形状:圆
// 设置形状红色边框
ES7中的装饰器
ES7中的装饰器其实就是对类进行装饰。
装饰器的原理:
@decorator
class A{}
//等同于
A = decorator(A) || A
配置环境:
npm install babel-plugin-transform-decorators-legacy --save-dev
- 修改.babelrc文件:
-
{ "presets": ["es2015","latest"], "plugins": ["transform-decorators-legacy"] }
装饰类:
@testDesc
class Demo{
}
function testDesc(target){
//这里的target其实就是被装饰的类Demo
console.log(target);
target.isDec = true;
}
console.log(Demo.isDec); //true
装饰器接收参数:
function testDec(isDec){
return function(target){
target.isDec = isDec;
}
}
//testDec(false)执行返回的是一个函数,函数再通过@关键字识别成装饰器,也就是返回的那个函数是一个装饰器
@testDec(false)
class Demo{
}
console.log(Demo.isDec); //false
装饰类 - mixin示例:
function mixins(...list) {
console.log(...list);
return function (target) {
Object.assign(target.prototype, ...list);
console.log(target.prototype);
}
}
const Foo = {
a: 2,
foo() {
console.log('foo');
}
}
//mixins(Foo)执行返回的是一个函数,函数再通过@关键字识别成装饰器,也就是返回的那个函数是一个装饰器
@mixins(Foo)
class Myclass {
}
let obj = new Myclass();
obj.foo();
结果:
Myclass里面本来是没有foo方法的,但通过装饰器给它添加了foo方法。
装饰方法 - readOnly示例:
function readOnly(target, name, descriptor) {
console.log(name);
descriptor.writable = false;
return descriptor;
}
class Person {
constructor() {
this.first = 'A';
this.last = 'B';
}
@readOnly
getName() {
return `${this.first} ${this.last}`
}
}
let p = new Person();
console.log(p.getName());
p.getName = function () {
//报错,getName是只读方法属性
}
结果:
//readonly基本介绍
function readonly(target,name,descriptor){
//target是类,name是当前的属性名
// descriptor是属性描述对象(Object.defineProperty 中会用到),原来的值如下:
// {
// value:specifiedFunction,
// enumerable:false,
// configurable:true,
// writable:true
// }
descriptor.writable = false;
return descriptor;
}
装饰方法 - log示例:
function log(target,name,descriptor){
let oldValue = descriptor.value;
console.log(oldValue);
descriptor.value = function(){
console.log(arguments);
return oldValue.apply(this,arguments);
}
}
class Math{
@log
add(a,b){
return a+b;
}
}
let m = new Math();
let result = m.add(1,6);
console.log(result);
结果:
直接引用第三方库core-decorators:
直接引用第三方开源的lib,可以提高工作效率。
import {readonly,deprecate} from 'core-decorators';
class Person{
// @readonly
// name(){
// return 'happychen';
// }
@deprecate
name(){
return 'happychen';
}
}
let p = new Person();
console.log(p.name());