zoukankan      html  css  js  c++  java
  • 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.
    

    设计原则验证

    • 将现有对象和装饰器进行分离,两者独立存在
    • 符合开放封闭原则
  • 相关阅读:
    shell内置命令eval的具有什么作用
    openwrt中如何在一个软件包中使能busybox中的工具
    go语言中strings包中的Trim函数的作用是什么
    RedisTemplate的各种操作(set、hash、list、string)
    Spring data redis-StringRedisTemplate 用法
    Spring-data-redis 第一天
    Java操作Redis数据
    BootStrap之X-editable插件使用
    bootstrap editable有默认值
    bootstrap editable初始化后表单
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12239038.html
Copyright © 2011-2022 走看看