zoukankan      html  css  js  c++  java
  • JavaScript-代理模式

    代理模式

    使用者无权访问目标对象
    中间加代理,通过代理授权和控制

    传统 UML 类图

    JavaScript 中的代理模式

    class ReadImg {
      constructor(fileName) {
        this.fileName = fileName;
        this.loadFromDisk();
      }
      display() {
        console.log("display..." + this.fileName);
      }
      loadFromDisk() {
        console.log("loading..." + this.fileName);
      }
    }
    
    class ProxyImg {
      constructor(fileName) {
        this.readImg = new ReadImg(fileName);
      }
      display() {
        this.readImg.display();
      }
    }
    
    // test
    let proxyImg = new ProxyImg("1.png");
    proxyImg.display();
    

    应用场景

    网页代理事件

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <div>
          <a href="#">a1</a>
          <a href="#">a2</a>
          <a href="#">a3</a>
          <a href="#">a4</a>
          <a href="#">a5</a>
        </div>
    
        <script src="https://cdn.bootcss.com/jQuery/3.3.0/jQuery"></script>
        <script>
          var div1 = document.getElementById("div1");
          div1.addEventListener("clink", function(e) {
            var target = e.target;
            if (target.nodeName === "A") {
              alert(target.innerHTML);
            }
          });
        </script>
      </body>
    </html>
    

    jQuery

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <div>
          <a href="#">a1</a>
          <a href="#">a2</a>
          <a href="#">a3</a>
          <a href="#">a4</a>
          <a href="#">a5</a>
        </div>
    
        <script src="https://cdn.bootcss.com/jQuery/3.3.0/jQuery"></script>
    
        <script>
          $("#div1").click(function() {
            // this符合期望
            $(this).addClass("red");
          });
          $("#div1").click(function() {
            setTimeout(function() {
              // this不符合期望
              $(this).addClass("red");
            }, 1000);
          });
        </script>
    
        <script>
          // 如下方式解决
          $("#div1").click(function() {
            // this符合期望
            $(this).addClass("red");
          });
          $("#div1").click(function() {
            var _this = this;
            setTimeout(function() {
              // this符合期望
              $(this).addClass("red");
            }, 1000);
          });
        </script>
      </body>
    </html>
    

    $.proxy

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <meta http-equiv="X-UA-Compatible" content="ie=edge" />
        <title>Document</title>
      </head>
      <body>
        <div>
          <a href="#">a1</a>
          <a href="#">a2</a>
          <a href="#">a3</a>
          <a href="#">a4</a>
          <a href="#">a5</a>
        </div>
    
        <script src="https://cdn.bootcss.com/jQuery/3.3.0/jQuery"></script>
        <script>
          $("#div1").click(function() {
            var fn = function() {
              $(this).css("background-color", "yellow");
            };
            fn = $.proxy(fn, this);
            setTimeout(fn, 1000);
          });
        </script>
    
        <script>
          // 由上面那个化简而来
          $("#div1").click(function() {
            fn = $.proxy(function() {
              $(this).css("background-color", "yellow");
            }, this);
            setTimeout(fn, 1000);
          });
        </script>
    
        <script>
          // 由上面那个化简而来
          $("#div1").click(function() {
            setTimeout(
              $.proxy(function() {
                $(this).css("background-color", "yellow");
              }, this),
              1000
            );
          });
        </script>
      </body>
    </html>
    

    es6 Proxy

    明星和经纪人的关系

    // 明星
    let star = {
      name: "张XX",
      age: 25,
      phone: "13910733521"
    };
    
    // 经纪人
    let agent = new Proxy(star, {
      get: function(target, key) {
        if (key === "phone") {
          // 返回经纪人自己的手机号
          return "18611112222";
        }
        if (key === "price") {
          // 明星不报价,经纪人报价
          return 120000;
        }
        return target[key];
      },
      set: function(target, key, val) {
        if (key === "customPrice") {
          if (val < 100000) {
            // 最低 10w
            throw new Error("价格太低");
          } else {
            target[key] = val;
            return true;
          }
        }
      }
    });
    
    // 主办方
    console.log(agent.name);
    console.log(agent.age);
    console.log(agent.phone);
    console.log(agent.price);
    
    // 想自己提供报价(砍价,或者高价争抢)
    agent.customPrice = 150000;
    // agent.customPrice = 90000  // 报错:价格太低
    console.log("customPrice", agent.customPrice);
    

    设计原则验证

    • 代理类和目标类分离,隔离开目标类和使用者
    • 符合开放封闭原则

    代理模式 VS 适配器模式

    • 适配器模式:提供一个不同的接口(如不同版本的插头)
    • 代理模式:提供一模一样的接口

    代理模式 VS 装饰器模式

    • 装饰器模式:拓展功能,原有功能不变且可直接使用
    • 代理模式:显示原有功能,但经过限制或阉割之后的
  • 相关阅读:
    如何过滤php中危险的HTML代码
    一个老总的语录
    php如何优化压缩的图片
    php时间函数time(),date(),mktime()区别
    php中获取网站访客来源的关键词方法
    php获取QQ头像并显示的方法
    php一些常规动态设置与获取
    xss过滤函数
    php获取当月的第一天以及最后一天
    php eval函数一句话木马代码
  • 原文地址:https://www.cnblogs.com/ygjzs/p/12239211.html
Copyright © 2011-2022 走看看