js设计模式学习笔记(四):装饰器模式

76 阅读1分钟

装饰器模式

特点

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

介绍

  • 在对象执行过程中动态的为这个对象添加新的方法或属性。这些新的方法、属性自身不属于这个对象。就像一个插件一样,安插在这个对象身上。需要的时候按上,不需要的时候就可以在这个对象身上去除。
  • 不同于继承,装饰者模式主旨在于动态的进行方法的装配。它保留原方法的执行过程,并在需要的位置进行添加方法或者属性。但是装饰者只能进行添加,但是不能对原有的方法的详情进行更改。
  • 但是在装饰者模式中,需要注意的是,我们如何规避 this 劫持的问题,可以使用 call/apply 函数解除
  • 例如在原方法执行之前进行检查。或者在原方法执行之后进行统计。没必要将原方法的代码进行重写,因为这违反单一原则。对于后期代码的维护要不是很方便。

demo

更多详细代码

  • 对函数装饰
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>函数装饰</title>
  </head>
  <body>
    <script>
      Function.prototype.before = function (fn) {
        var _self = this;
        return function () {
          fn.apply(_self);
          _self.apply(this);
        };
      };

      Function.prototype.after = function (fn) {
        var _self = this;
        return function () {
          var ret = _self.apply(this);
          fn.apply(_self);
          return ret;
        };
      };

      var test = function () {
        console.log("show 2");
      };

      test = test.before(function () {
        console.log("show 1");
      });

      test = test.after(function () {
        console.log("show 3");
      });

      test();
    </script>
  </body>
</html>

  • 对参数装饰
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>参数装饰</title>
  </head>
  <body>
    <script>
      Function.prototype.addParam = function (fn) {
        var _self = this;
        return function () {
          fn.apply(_self, arguments);
          return _self.apply(this, arguments);
        };
      };

      test = function (param) {
        return param;
      };

      test = test.addParam(function (param) {
        param.b = "b";
      });

      const param = test({ a: "a" });
      console.log(param);
    </script>
  </body>
</html>