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

Posted 三水草肃

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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. 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. 可以看到 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" );
        
    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
        

以上是关于JavaScript设计模式中的装饰者模式的主要内容,如果未能解决你的问题,请参考以下文章

javascript设计模式:装饰者模式

javascript设计模式:装饰者模式

深入理解JavaScript系列(29):设计模式之装饰者模式

JavaScript设计模式与开发实践 装饰者模式

javascript设计模式——装饰者模式

Javascript设计模式之装饰者模式详解篇