介绍

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

    示例

  • 科学上网,访问 GitHub.com

  • 明星经纪人

    常见使用场景

  • 网页事件代理 ```html <!DOCTYPE html>

  1. - jQuery$.proxy
  2. ```html
  3. <!DOCTYPE html>
  4. <html lang="en">
  5. <head>
  6. <meta charset="UTF-8" />
  7. <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  8. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  9. <title>Document</title>
  10. </head>
  11. <body>
  12. <div id="div1">
  13. <a href="#">a1</a>
  14. <a href="#">a2</a>
  15. <a href="#">a3</a>
  16. <a href="#">a4</a>
  17. <a href="#">a5</a>
  18. <a href="#">a6</a>
  19. </div>
  20. <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
  21. <script>
  22. // $("#div1").click(function () {
  23. // $(this).addClass("red");
  24. // });
  25. // $("#div1").click(function () {
  26. // setTimeout(function () {
  27. // // this 不符合期望
  28. // $(this).addClass("red");
  29. // }, 1000);
  30. // });
  31. // $("#div1").click(function () {
  32. // var _this = this;
  33. // setTimeout(function () {
  34. // // _this 符合期望
  35. // $(_this).addClass("red");
  36. // }, 1000);
  37. // });
  38. // $("#div1").click(() => {
  39. // setTimeout(() => {
  40. // $(this).addClass("red");
  41. // }, 1000);
  42. // });
  43. $("#div1").click(function () {
  44. setTimeout(
  45. $.proxy(function () {
  46. $(this).addClass("red");
  47. }, this),
  48. 1000
  49. );
  50. });
  51. </script>
  52. </body>
  53. </html>
  • es 6的proxy ```javascript //明星 let star = { name: “dd”, age: 25, phone: “明星电话:189**05“, };

//经纪人 let agent = new Proxy(star, { //target是要代理的对象,key是要获取的属性值 get: function (target, key) { if (key === “phone”) { //返回经纪人的电话,不会把明星的电话直接给你 return “经纪人电话:189**3*”; } if (key === “price”) { //明星不报价,经纪人谈价格 return “12K”; } return target[key]; }, set: function (target, key, value) { if (key === “customPrice”) { if (value < 100000) { //最低10万 throw new Error(“价格太低”); } else { target[key] = value; return true; } } }, });

console.log(agent.name); console.log(agent.phone); console.log(agent.price);

agent.customPrice = 150000; console.log(“agent.customPrice:” + agent.customPrice);

  1. <a name="i9iMF"></a>
  2. # 代理模式代码示例
  3. ```javascript
  4. class ReadImg {
  5. constructor(fileName) {
  6. this.fileName = fileName;
  7. this.loadFromDisk();
  8. }
  9. dispaly() {
  10. console.log("display... " + this.fileName);
  11. }
  12. loadFromDisk() {
  13. console.log("loading... " + this.fileName);
  14. }
  15. }
  16. class ProxyImg {
  17. constructor(fileName) {
  18. this.realImg = new ReadImg(fileName);
  19. }
  20. dispaly() {
  21. this.realImg.dispaly();
  22. }
  23. }
  24. // test
  25. let proxyImg = new ProxyImg("pic.png");
  26. proxyImg.dispaly();

设计原理验证

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


区分

代理模式 VS 适配器模式

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

代理模式 VS 装饰器模式

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