ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript-代理模式

2020-01-28 22:51:16  阅读:177  来源: 互联网

标签:function console target JavaScript 代理 模式 fileName agent div1


代理模式

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

传统 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 装饰器模式

  • 装饰器模式:拓展功能,原有功能不变且可直接使用
  • 代理模式:显示原有功能,但经过限制或阉割之后的

标签:function,console,target,JavaScript,代理,模式,fileName,agent,div1
来源: https://www.cnblogs.com/ygjzs/p/12239211.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有