范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

前端必须懂的设计模式代理模式

  动机由于一个对象不想或者不能直接引用另外一个对象,所以需要通过通过一个称之为"代理"的第三者来实现间接引用 代理模式就是为目标对象创造一个代理对象,在客户端和目标对象之间起到中介的作用 这样就可以在代理对象里增加一些逻辑判断、调用前或调用后执行一些操作,从而实现了扩展目标的功能 并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务
  通过引入一个新的对象(如小图片和远程代理对象)来实现对真实对象的操作或者将新的对 象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一 个对象,这就是代理模式的模式动机。 定义
  代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英 文叫做Proxy或Surrogate,它是一种对象结构型模式。 生活中的案例:
  火车票代购、房产中介、律师、海外代购、明星经纪人 类图和时序图
  代理模式包含如下角色: Subject: 抽象主题角色 Proxy: 代理主题角色 RealSubject: 真实主题角色 类图
  时序图
  一个例子-明星经纪人
  abstract class Star {     abstract answerPhone(): void; }  class Angelababy extends Star {     public available: boolean = true;     answerPhone(): void {         console.log("你好,我是Angelababy.");     } } class AngelababyAgent extends Star {     constructor(private angelababy: Angelababy) {         super();     }     answerPhone(): void {         console.log("你好,我是Angelababy的经纪人.");         if (this.angelababy.available) {             this.angelababy.answerPhone();         }     } } let angelababyAgent = new AngelababyAgent(new Angelababy()); angelababyAgent.answerPhone(); 场景事件委托代理事件捕获指的是从document到触发事件的那个节点,即自上而下地去触发事件 事件冒泡是自下而上地去触发事件 绑定事件方法的第三个参数,就是控制事件触发顺序是否为事件捕获。true为事件捕获;false为事件冒泡,默认false。
       
  • 1
  • 2
  • 3
虚拟代理(图片预加载)app.jslet express=require("express"); let path=require("path") let app=express(); app.get("/images/loading.gif",function (req,res) { res.sendFile(path.join(__dirname,req.path)); }); app.get("/images/:name",function (req,res) { setTimeout(() => { res.sendFile(path.join(__dirname,req.path)); }, 2000); }); app.get("/",function (req,res) { res.sendFile(path.resolve("index.html")); }); app.listen(8080); index.html Document 虚拟代理(图片懒加载)当前可视区域的高度 window.innerHeight || document.documentElement.clientHeight 元素距离可视区域顶部的高度 getBoundingClientRect().top getBoundingClientRect DOMRect 对象包含了一组用于描述边框的只读属性——left、top、right 和 bottom,单位为像素。除了 width 和 height 外的属性都是相对于视口的左上角位置而言的 Lazy-Load 缓存代理   有些时候可以用空间换时间 正整数的阶乘(factorial)   一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1 const factorial = function f(num) { if (num === 1) { return 1; } else { return (num * f(num - 1)); } } const proxy = function (fn) { const cache = {}; // 缓存对象 return function (num) { if (num in cache) { return cache[num]; // 使用缓存代理 } return cache[num] = fn.call(this, num); } } const proxyFactorial = proxy(factorial); console.log(proxyFactorial(5)); console.log(proxyFactorial(5)); console.log(proxyFactorial(5)); 斐波那契数列(Fibonacci sequence)   指的是这样一个数列:1、1、2、3、5、8、13、21、34。在数学上,斐波那契数列以如下被以递推的方法定义:F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)(n>=3,n N*) let count = 0; function fib(n) { count++; return n <= 2 ? 1 : fib(n - 1) + fib(n - 2); } var result = fib(10); console.log(result, count);//55 110 let count = 0; const fibWithCache = (function () { let cache = {}; function fib(n) { count++; if (cache[n]) { return cache[n]; } let result = n <= 2 ? 1 : fib(n - 1) + fib(n - 2); cache[n] = result; return result; } return fib; })(); var result = fibWithCache(10); console.log(result, count);//55 17 防抖代理通过防抖代理优化可以把多次请求合并为一次,提高性能 节流与防抖都是为了减少频繁触发事件回调 节流(Throttle)是在某段时间内不管触发了多少次回调都只认第一个,并在第一次结束后执行回调 防抖(Debounce)就是在某段时间不管触发了多少回调都只看最后一个 节流 Document 防抖 Document 防抖案例 -未防抖
  app.js let express=require("express"); let app=express(); app.use(express.static(__dirname)); let todos=[ {id: 1,text: "a",completed: false}, {id: 2,text: "b",completed: false}, {id: 3,text: "c",completed: false}, ]; app.get("/todos",function (req,res) { res.json(todos); }); app.get("/toggle/:id",function (req,res) { let id=req.params.id; todos = todos.map(item => { if (item.id==id) { item.completed=!item.completed; } return item; }); res.json({code:0}); }); app.listen(8080); 防抖案例 -防抖   todos.html
  app.js app.get("/toggle/:ids",function (req,res) { let ids=req.params.ids; ids=ids.split(",").map(item=>parseInt(item)); todos = todos.map(item => { if (ids.includes(item.id)) { item.completed=!item.completed; } return item; }); res.json({code:0}); }); 代理跨域正向代理正向代理的对象是客户端,服务器端看不到真正的客户端 通过公司代理服务器上网   反向代理反向代理的对象的服务端,客户端看不到真正的服务端 nginx代理应用服务器   proxy-server.js const http = require("http"); const httpProxy = require("http-proxy"); //创建一个代理服务 const proxy = httpProxy.createProxyServer(); //创建http服务器并监听8888端口 let server = http.createServer(function (req, res) { //将用户的请求转发到本地9999端口上 proxy.web(req, res, { target: "http://127.0.0.1:9999" }); //监听代理服务错误 proxy.on("error", function (err) { console.log(err); }); }); server.listen(8888, "0.0.0.0");   real-server.js const http = require("http"); let server = http.createServer(function (req, res) { res.end("9999"); }); server.listen(9999, "0.0.0.0"); 代理跨域nginx代理跨域 webpack-dev-server 代理跨域客户端代理跨域 当前的服务启动在origin(3000端口)上,但是调用的接口在target(4000端口)上 postMessage方法可以安全地实现跨源通信 otherWindow:其他窗口的一个引用 message:将要发送到其他window的数据message 将要发送到其他window的数据targetOrigin通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI otherWindow.postMessage(message, targetOrigin, [transfer]); data 从其他window中传递过来的对象 origin 调用postMessage时消息发送方窗口的origin source 对发送消息的窗口对象的引用 window.addEventListener("message", receiveMessage, false);   origin.js let express=require("express"); let app=express(); app.use(express.static(__dirname)); app.listen(3000);   target.js let express = require("express"); let app = express(); let bodyParser = require("body-parser"); app.use(bodyParser.urlencoded({ extended: true })); app.use(express.static(__dirname)); let users = []; app.post("/register", function (req, res) { let body = req.body; let target = body.target; let callback = body.callback; let username = body.username; let password = body.password; let user = { username, password }; let id = users.length == 0 ? 1 : users[users.length - 1].id + 1; user.id = id; users.push(user); res.status(302); res.header("Location", `${target}?callback=${callback}&args=${id}`); res.end(); }); app.listen(4000);   reg.html Document   target.html Document $.proxy接受一个函数,然后返回一个新函数,并且这个新函数始终保持了特定的上下文语境。 jQuery.proxy( function, context ) function为执行的函数,content为函数的上下文this值会被设置成这个object对象 jquery proxy function proxy(fn, context) { return function () { return fn.call(context, arguments); } } ProxyProxy 用于修改某些操作的默认行为 Proxy 可以理解成,在目标对象之前架设一层 拦截 ,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来 代理 某些操作,可以译为代理器 Proxy defineProperty let wang={ name: "wanglaoshi", age: 29, height:165 } let wangMama=new Proxy(wang,{ get(target,key) { if (key == "age") { return wang.age-1; } else if (key == "height") { return wang.height-5; } return target[key]; }, set(target,key,val) { if (key == "boyfriend") { let boyfriend=val; if (boyfriend.age>40) { throw new Error("太老"); } else if (boyfriend.salary<20000) { throw new Error("太穷"); } else { target[key]=val; return true; } } } }); console.log(wangMama.age); console.log(wangMama.height); wangMama.boyfriend={ age: 41, salary:3000 } Vue2和Vue3   Vue2 中的变化侦测实现对 Object 及 Array 分别进行了不同的处理,Object 使用了 Object.defineProperty API,Array使用了拦截器对 Array 原型上的能够改变数据的方法进行拦截。虽然也实现了数据的变化侦测,但存在很多局限 ,比如对象新增属性无法被侦测,以及通过数组下边修改数组内容,也因此在 Vue2 中经常会使用到 $set 这个方法对数据修改,以保证依赖更新。   Vue3 中使用了 es6 的 Proxy API对数据代理,没有像 Vue2 中对原数据进行修改,只是加了代理包装,因此首先性能上会有所改善。其次解决了 Vue2 中变化侦测的局限性,可以不使用 $set 新增的对象属性及通过下标修改数组都能被侦测到。 对比代理模式 VS 适配器模式   适配器提供不同接口,代理模式提供一模一样的接口 代理模式 VS 装饰器模式   装饰器模式原来的功能不变还可以使用,代理模式改变原来的功能

NASA调整韦伯望远镜的观测时间表以尽量减少微流星体撞击的威胁为设计建造和发射詹姆斯韦伯太空望远镜,NASA的科学家们进行了数十年的工作,这是有史以来最大和最先进的观测站。美国宇航局对在太空中操作飞船的危险性有一定的了解,并据此建造了韦伯。其联芸主控性能靠谱七彩虹CN700PCle4。0固态硬盘评测写在前面内存颗粒国产化后,市场环境对于DIY玩家来说越来越友好,价格美丽量又足,之前做过好几款使用国产颗粒的内存,性价比那是相当高。对于SSD来说,可能大部分人使用的还是PCle3苹果原装线相同快充体验,魅族PANDAERMFi认证CtoLightning线拆解前言苹果手机自带的Lightning数据线以不耐用著称,其采用的环保材质在使用一段时间后会开裂损坏,影响使用。苹果也意识到这个问题,在iMac中标配了一条编织线,延长线缆的使用寿命学会管理自己的业力,经营好自己的人生如果在你的生活当中有诸多不顺心的事儿,遇到了很多让你消耗的关系,我们大家要觉察一下,是不是自己曾经种下了这样的因,导致今天会有这样的果。万般带不去,唯有业随身。每个人都是在自己的业我和你在一起的浪漫让我们相爱吧时间只有一天让我们抓住所有的浪漫佩索阿我不能不赞美这向晚的五月天怀抱着云和树那些玲珑的水田徐志摩车眺我曾经想用一句话概括有关世间爱的迷茫,那就是刻意将假象与真相结合的迷人生的等待人的一生在等待中度过,尤其是在体制内工作的人。体制内工作的人,他们面临的最大压力就是竞争。他们为提拨晋级而费尽心思。一次机会的到来,他们会使出浑身的解数去拼关系。一次机会过后,他们所罗门王一生如何追寻的人生意义?有一位老人在回顾他一生的时候,好像在主持一场辩论,但这场辩论是在他脑中进行。他给正反两方平等的机会来发表意见。他先听脑中反方的意见,再听正方的意见。辩论的主题是人生到底值不值得活?人生何处不清欢,何必躺平独自伤时而颓废,不思进取时而佛系,无欲无求时而自闭,逃避现实,这就是躺平的表现。支持躺平的人说躺平是一种无奈,也是一种无声的呐喊躺平是年轻人的非暴力不合作运动只要我们躺平,你就割不到我。朱永新如何让孩子放下手机捧起书籍?父母是孩子的第一任教师,推动世界的手就是摇摇篮的手。让父母重视幼儿的精神成长,让父母意识到幼儿阅读的重要性,让父母学会怎样给孩子选书读书,在这些父母需要的时候,提供有效帮助,这是目黑龙江吉林和辽宁的3道硬核下酒菜,哪道是东北之魂?导语黑龙江吉林和辽宁的3道硬核下酒菜,哪道是东北之魂?既然有杭州北京等美食荒漠,那必然有东北川渝等美食宝地,这从诸多老外up主拍摄的短视频中就能看出来,想遍尝中国美食,没想到两三年冬天,孩子最馋这道下饭菜,2种食材随手一炒,鲜香滑嫩超下饭入冬后,家人的食欲好了不少,日常做饭时,我也会经常做一些简单美味的下饭菜,让家人吃得营养又健康。家常下饭菜的烹饪方法不难,最重要的就是掌握好食材的搭配,用新鲜蔬菜和富含蛋白质的食材
田亮为儿子庆生,10岁亮仔超像爸爸,一家人共用一张脸傻傻分不清11月8日是田亮儿子小亮仔10岁生日,当天晚上,叶一茜田亮先后发文为儿子庆生。叶一茜配文表示9岁顺利通关的小朋友生日快乐,今天开始你就是10岁的小男子汉了。并晒出一组小亮仔的写真照如果李宇春周笔畅张靓颖何洁同一天开演唱会,你会选择谁?假如四人同时开演唱会,必须要选一个的话,我会选择李宇春。为什么呢?我们先简单分析一下这四位歌手。第一个李宇春普通家庭出身,2005年超女冠军,后来无论是歌坛还是影坛获奖无数,凭借其章子怡晒一家五口出游照,16岁继女女大十八变,小儿子现场秀画艺提起如今的章子怡,她可谓是圈内的人生赢家,不仅事业方面发展顺利,同时家庭和睦,十分引人羡慕。就在前阵子,对方刚刚晒出了一家人过万圣节的照片,而在近日,她又通过网络晒出了一家五口人一适合天冷冬天发的文案1。又到了手脚冰凉怎么都捂不热的季节了,风已经有了冬天的味道,搓搓手,我要一个人过冬天了。2。接下来的日子,把衣服穿厚一点,走路慢一点,睡觉早一点,这个冬天有点冷,照顾好自己。3。2021年冬天的第一场雪,比以往时候来得更早一些秋日好时光2021年冬天的第一场雪,是伴随着入冬的第一天一同而来的。虽然说,天气预报早早的就预报这天有雪。但是,我并没有想到今年冬天的第一场雪会来得这么早,更没有想到这场雪会如约而很惊艳的简单句子吸引人的简短文案1。所谓的浪漫主义不再和世界赌气2。被爱当然很好如果没有也没关系。3。我的肩上是风风上是闪烁的星群4。人终将为年少不可得之物困扰一生5。天气降温了爱意可以升温吗6。愿所得皆所期,所冬季养生,4件小事做到,养气补血,整个冬天不生病,健康保平安冬季养生,做好4件小事,顺应时节,养气血,来年才会气色红润,生机勃发,让你整个冬天不生病,健康保平安立冬过后,冬天就来到了。经过了春夏秋季的洗礼,人体在冬季要好好的修养,冬天是收藏描写冬天的作文素材大全,有好词好句好段,孩子正好用得上欢迎关注我,我是小学教师,自由撰稿人,热爱读书与音乐。众所周知的是,一年四季分别是春夏秋冬。冬季是最后一个季节,也是最寒冷的季节。一般情况下,到了立冬这个节气,就意味着冬季的来临。你了解比通胀更可怕的通货紧缩吗?通货膨胀和通货紧缩属于经济学中的一组概念,通货膨胀主要是由于货币供应量大于货币需求量,造成货币的贬值,具体表现为社会整体商品价格不断上涨而通货紧缩则刚刚相反,货币在升值,具体表现为难过的时候,别发朋友圈有时候真不知道活着的意义到底是什么。这是好友昨晚十二点三十五分发的一条朋友圈。看到之后给我吓懵了,以为他想不开要寻短见,于是立马给他发消息打电话,准备安慰一下他,但是没想到他手机竟人生感悟语录人生,总会有不期而遇的温暖,和生生不息的希望。在人来人往,聚散分离的人生旅途中,在各自不同的生命轨迹上,在不同经历的心海中,能够彼此相遇相聚相逢,可以说是一种幸运,缘份不是时刻都会