1. 정의
프록시 패턴: 객체에 대한 액세스를 제어하기 위해 객체에 대한 대리자 또는 자리 표시자를 제공합니다.
에이전트는 보호 에이전트와 가상 에이전트
로 구분됩니다.
보호 에이전트: 는 대상 개체에 대해 서로 다른 권한을 가진 개체의 접근을 제어하는 데 사용됩니다. JavaScript에서는 개체에 누가 접근했는지 판단하기 어렵기 때문에 보호 에이전트가 어렵습니다. 구현합니다.
2. 이미지 사전 로딩(가장 일반적인 가상 에이전트 적용 시나리오)
이미지 미리 로드는 img 태그 노드에 대한 src 속성을 직접 설정하는 경우 이미지가 너무 크거나 네트워크 상태가 좋지 않아 이미지 위치가 한동안 비어 있는 경우가 많습니다. 일반적인 접근 방식은 미리 로딩 이미지를 자리 표시자로 사용한 다음, 이미지가 로드된 후 이미지를 img 노드에 채우는 것입니다.
구현 원칙:
이미지 객체 생성: var a = new Image()
이미지 객체의 src를 정의합니다: a.src = “xxx.gif”
이는 브라우저용 이미지를 캐싱하는 것과 같습니다.
이미지 객체의 완전한 속성을 통해 이미지 로딩 여부를 확인할 수 있습니다. 각 이미지 객체에는 완전한 속성이 있습니다. 이미지가 로드되는 동안 속성 값은 onload, onerror 및 onabort 이벤트가 발생하면 이미지 로드 프로세스가 끝났음을 의미합니다. 완전한 속성은 true입니다.
(1) 비 프록시 구현
var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); var img = new Image(); img.onload = function() { imgNode.src = img.src; }; return { setSrc: function(src) { imgNode.src = "./images/loading.gif"; img.src = src; } } })(); myImage.setSrc("./images/originImg.png");
(2) 프록시 구현
// 创建图片DOM var myImage = (function() { var imgNode = document.createElement("img"); document.body.appendChild(imgNode); return { setSrc: function(src) { imgNode.src = src; } }; })(); // 代理 var proxyImage = (function() { var img = new Image(); img.onload = function() { myImage.setSrc(this.src); // this指向img!img加载完成后,将img.src传递给myImage }; return { setSrc: function(src) { myImage.setSrc("./images/loading.gif"); // loading img.src = src; } }; })(); proxyImage.setSrc("./images/originImg.png");
프록시 모드 사용의 이점: 각 기능을 단일 기능으로 만들고 객체 디자인의 "단일 책임 원칙"을 실현합니다!
3. 파일 동기화
파일 동기화 기능을 수행 중이라고 가정해 보겠습니다. 확인란을 선택하면 해당 파일이 다른 서버로 동기화됩니다.
<body> <input type="checkbox" id="1" />文件1 <input type="checkbox" id="2" />文件2 <input type="checkbox" id="3" />文件3 <input type="checkbox" id="4" />文件4 <input type="checkbox" id="5" />文件5 <input type="checkbox" id="6" />文件6 </body>
체크박스를 선택하지 않고 한 번 동기화하는 것은 당연히 무리입니다. 웹 개발에서 가장 큰 오버헤드는 네트워크 요청이기 때문입니다.
해결책: 프록시 기능을 사용하여 일정 시간 내에 요청을 수집한 후 한꺼번에 서버에 보냅니다.
var synchronousFile = function(id) { console.log("开始同步文件,id为:" + id); }; var proxySynchonousFile = (function() { var cache = [], // 保存本次需要同步文件的id timer; // 定时器 return function(id) { cache.push(id); if(timer) { // 不要覆盖已经启动的定时 return; } timer = setTimeout(function(){ synchronousFile(cache.join(",")); clearTimeout(timer); timer = null; cache.length = 0; // 清空缓存 }, 2000); } })(); var checkboxs = document.getElementsByTagName("input"); for(var i = 0, c; c = checkboxs[i]; i++) { c.onclick = function() { if(this.checked === true) { proxySynchonousFile(this.id); } } }
4. 캐싱 프록시 - 곱 계산(순서는 정확히 동일함)
var mult = function() { var result = 1; for(var i = 0, l = arguments.length; i < l; i++) { result= result * arguments[i]; } return result; }; var proxyMult = (function() { var cache = {}; // {"1,2,3": 6} return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = mult.apply(this, arguments); } })(); console.log(proxyMult(1, 2, 3)); // 改造: var proxyFactory = function(fn) { var cache = {}; return function() { var args = Array.prototype.join.call(arguments, ","); if(args in cache) { return cache[args]; } return cache[args] = fn.apply(this, arguments); } }; console.log(proxyFactory(mult)(1, 2, 3));
이 기사가 JavaScript 프로그래밍을 배우는 모든 사람에게 도움이 되기를 바랍니다.