JavaScript-装饰器模式

装饰器模式

为对象添加新功能
不改变其原有的结构和功能

传统 UML 类图

javascript 中的装饰器

装饰类


@testDec
clss Demo {

}

function testDec(target) {
    target.isDec = true
}

alert(Demo.isDec)

@testDec(false)
clss Demo {

}

function testDec(isDec) {
    return function (target) {
        target.isDec = isDec
    }
}

alert(Demo.isDec)

装饰器原理

@decorator
class A {}

//等同于

class A {}
A = decorator(a) || A;

装饰类-mixin 示例

function mixins(...list) {
  return function(target) {
    Object.assign(target.prototype, ...list);
  };
}

const Foo = {
  foo() {
    alert("foo");
  }
};

@mixins(Foo)
class MyClass {}

let obj = new MyClass();
obj.foo(); // 'foo'

装饰方法

one

function readonly(target, name, descriptor) {
  // descriptor对象原来的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}

class Person {
  constructor() {
    this.first = "A";
    this.last = "B";
  }

  @readonly
  name() {
    return `${this.first} ${this.last}`;
  }
}

var p = new Person();
console.log(p.name()); // 调用方法
p.name = function() {}; // 这里会报错,因为 name 是只读属性

two

function log(target, name, descriptor) {
  var 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();
const result = math.add(2, 4);
console.log("result", result);

core-decorators

  • 第三方开源 lib
  • 提供常用的装饰器
  • 文档
  • 执行npm i core-decorators --save

使用

想用什么装饰器,直接引入就行了

one
import { readonly } from "core-decorators";

class Person {
  @readonly
  name() {
    return "zhang";
  }
}

let p = new Person();
alert(p.name());
// p.name = function () { /*...*/ }  // 此处会报错

two

import { deprecate } from "core-decorators";

class Person {
  @deprecate
  facepalm() {}

  @deprecate("We stopped facepalming")
  facepalmHard() {}

  @deprecate("We stopped facepalming", {
    url: "http://knowyourmeme.com/memes/facepalm"
  })
  facepalmHarder() {}
}

let person = new Person();

person.facepalm();
// DEPRECATION Person#facepalm: This function will be removed in future versions.

person.facepalmHard();
// DEPRECATION Person#facepalmHard: We stopped facepalming

person.facepalmHarder();
// DEPRECATION Person#facepalmHarder: We stopped facepalming
//
//     See http://knowyourmeme.com/memes/facepalm for more details.

设计原则验证

  • 将现有对象和装饰器进行分离,两者独立存在
  • 符合开放封闭原则
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值