代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问
1、保护代理
用于控制不同权限的对象对目标的访问
js
function login() {
console.log('欢迎欢迎');
}
function proxyLogin(role) {
if(role==='vip) {
login();
} else {
console.log('你还没有成为vip哦,请先blabla');
}
}
2、虚拟代理
用于控制对创建开销很大的本体访问,它会把本体的实例化推迟到有方法被调用的时候,是最常用的一种代理
js
// 图片懒加载
const myImage = (function(){
const img = document.createElement('img');
document.body.appendChild(img);
return {
setSrc(src) {
img.src = src;
}
}
})();
// 代理
const proxyImage = (function(){
const img = new Image();
img.onload = function() {
myImage.setSrc(this.src);
}
return {
setSrc(src) {
myImage.setSrc('./loding.png');
img.src = src;
}
}
})();
proxyImage.setSrc('./bigpic.jpg');
// 函数防抖,频繁操作中不处理,直到操作完成之后(再过 delay 的时间)才一次性处理,执行最后一次操作
function debounce(fn, delay) {
delay = delay || 200;
var timer = null;
return function() {
// 每次操作时,清除上次的定时器
clearTimeout(timer);
timer = null;
const args = arguments;
// 定义新的定时器,一段时间后进行操作
timer = setTimeout(function() {
fn.apply(this, args);
}, delay);
}
};
// 函数节流
/**
* @param {Number} wait 一段时间内不再执行 单位ms
*/
function throttle(fn, wait) {
wait = wait || 200;
var lastTime = 0; // 上一次执行时间
return function() {
var nowTime = Date.now();
if(nowTime - lastTime > wait) {
lastTime = nowTime;
fn.apply(this, arguments);
}
}
}
var count = 0;
// 主体
function scrollHandle(e) {
console.log(e.type, ++count); // scroll
}
// 代理
var proxyScrollHandle = (function() {
return debounce(scrollHandle, 500);
})();
window.onscroll = proxyScrollHandle;
3、缓存代理
缓存代理 可以为一些开销大的运算结果提供暂时的缓存,在下一次运算时,如果传递进来的参数跟之前一致,则可以直接返回前面存储的运算结果
4、基于es6的proxy的代理
可用作表单验证
js
const driver = {
age: 18,
name: '小明'
};
const proxyDriver = new Proxy(driver, {
get(target, key) {
let result = target[key];
//如果是获取 年龄 属性,则添加 岁字
if (key === 'age') result += '岁';
return result;
},
set(target, key, value) {
if (key === 'age' && typeof value !== 'number') {
throw Error('年龄必须为数字');
}
if(value<18) {
throw Error('驾驶员必须满18岁哦!')
})
return Reflect.set(target, key, value);
}
});
console.log(`我叫${proxyDriver.name} 我今年${proxyDriver.age}了`);
proxyDriver.age = '15';