• JavaScript设计模式中的装饰者模式


    装饰者模式

    给对象动态添加职责的模式是装饰者模式。装饰者能够在不改变对象自身的基础上,在程序运行前给对象动态地添加职责。跟继承相比,装饰者是轻便灵活的模式

    装饰者模式和代理者模式

    1. 当直接访问本体不方便或者不符合需要时,为这个本体提供一个替代者。为对象动态加入行为。

    2. 代理模式强调一种关系,这种关系可以静态的表达,也就是说,这种关系一开始就可以被确定。而装饰者用于一开始不能确定对象的全部功能时。

    3. 代理模式通常只有一层代理-本体的作用,而装饰者模式经常会形成一条长长的装饰链。

      Function.prototype.after = function (afterFn) {
        const _self = this;
        return function () {
          const ret = _self.apply(this, arguments);
          afterFn.apply(this, arguments);
          return ret;
        };
      };
      
      const log1 = function () {
        console.log("上报标签为:", this.getAttribute("tag"));
      };
      
      let showLogin1 = function () {
        console.log("登录");
      };
      
      showLogin1 = showLogin1.after(log1);
      document.getElementById("button").onclick = showLogin1;
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      1. AOP 可修改函数的参数

        1. AOP 的 before 代码
        Function.prototype.before = function (beforeFn) {
          // 保存原函数的引用
          const _self = this;
          // 返回包含原函数和新函数的代理函数
          return function () {
            beforeFn.apply(this, arguments); // 执行 before 新函数
            return _self.apply(this, arguments); // 执行 func 函数并返回原函数的执行结果
          };
        };
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        1. 可以看到 beforeFn 和原函数_self 公用一组参数列表 arguemnts,当我们在 beforeFn 的函数体内改变 arguments 的时候,_self 接受的参数也会改变。

        2. 使用场景:给 ajax 新增参数;

          1. 用 AOP 的方式给 ajax 函数动态装饰上 token 参数,保证了 ajax 函数是一个相对纯净的函数,提高了 ajax 的可复用性,他在被迁移其他项目的时候,不需要做任何修改。
          Function.prototype.before = function (beforeFn) {
            // 保存原函数的引用
            const _self = this;
            // 返回包含原函数和新函数的代理函数
            return function () {
              beforeFn.apply(this, arguments); // 执行 before 新函数
              return _self.apply(this, arguments); // 执行 func 函数并返回原函数的执行结果
            };
          };
          
          let ajax = (type, url, params) => {
            console.log(params);
          };
          
          ajax = ajax.before(function (type, url, param) {
            param.header = "application/json";
          });
          ajax("type", "xx", { token: "token" });
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
      2. 使用 AOP 的弊端

        1. before 和 after 被装饰之后,返回的是一个新的函数,如果在原函数上保存了一些属性,那么原有属性会丢失。
          let fnc = function () {
            console.log(1);
          };
          fnc.a = "1";
          
          fnc = fnc.before(() => {
            console.log(1);
          });
          
          console.log(fnc.a); // undefined
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
  • 相关阅读:
    [附源码]Python计算机毕业设计Django人事管理系统
    离线笔记软件
    斩获双奖|易知微荣获“2021中国数字孪生解决方案优秀供应商”“中国智能制造优秀推荐产品”双奖项!
    Bootstrap Blazor 组件库 Row 布局组件(栅格系统)
    我为什么错怪了goroutine
    心理测评测试h5公众号字节微信小程序app开源版开发
    Linux/Windows中创建共享文件夹
    笔试刷题Day—1
    MybatisPlus【SpringBoot】 6 插件 6.3 乐观锁
    英汉互译在线翻译器-大家都在用的英汉互译翻译器
  • 原文地址:https://blog.csdn.net/weixin_43405946/article/details/127858541