JavaScript设计模式:代理模式详解与实战应用
本文深入解析JavaScript结构型设计模式中的代理模式,通过明星经纪人与粉丝互动的通俗案例,阐述其控制访问的核心定义。详细区分并实现保护代理与虚拟代理,重点展示如何利用虚拟代理优化图片预加载与懒加载逻辑,帮助开发者掌握对象访问控制的实战技巧。
概述
代理模式是结构型设计模式的一种。
定义:
其核心是为一个对象提供代用品或占位符,从而实现对原对象访问的控制。
白话解释:
以明星经纪人为例,粉丝若想联系明星进行商演或演唱会等商业活动,需先与经纪人沟通。双方达成合作意向后,由经纪人向明星转达,明星再决定是否参与。租房场景同理,用户通常通过链家等中介平台与房东沟通,中介代理了房东的房源信息,用户无需直接与房东打交道。
实现方法
举例说明:
假设你是一名忠实粉丝,恰逢某明星生日,你打算赠送礼物表达心意。常规流程如下:
var Fans = {
flower(){
star.reception("花");
}
}
var star = {
reception:function(gift){
console.log("收到粉丝的:"+gift);
}
}
Fans.flower(); //收到粉丝的:花
你选择购买鲜花并寄送给明星,希望传递心意。然而,现实情况往往复杂,因为签收礼物的通常不是明星本人,而是其经纪人:
var Fans = {
flower(){
Agent.reception("花");
}
}
var Agent = {
reception:function(gift){
console.log("粉丝送的:"+gift); //粉丝送的:花
star.reception("花");
}
}
var star = {
reception:function(gift){
console.log("收到粉丝的:"+gift);
}
}
Fans.flower(); //收到粉丝的:花
在此场景中,经纪人充当了简单的代理角色。粉丝需先将礼物交给经纪人,再由经纪人转交明星本人。
保护代理
当明星收到粉丝寄来的包裹并打开发现是鲜花时,表示不屑,并指示经纪人:今后所有寄送的鲜花一律拒收,由经纪人自行处理。
var Fans = {
flower(){
Agent.reception("花");
}
}
var Agent = {
reception:function(gift){
console.log("粉丝送的:"+gift); //粉丝送的:花
if(gift != "花"){
star.reception("花");
}
}
}
var star = {
reception:function(gift){
console.log("收到粉丝的:"+gift);
}
}
Fans.flower();
在上述程序中,明星实际上并未收到鲜花,因为经纪人已在接收环节进行了拦截和处理。通过经纪人过滤特定礼物的机制,被称为保护代理。
虚拟代理
既然送花无法送达,粉丝改变策略,决定直接赠送现金以便明星自行购买所需物品。粉丝将一百万现金交给经纪人,委托其转达给明星。
function Money(){
this.total = "一百万现金"
return this.total;
}
var Fans = {
flower(){
Agent.reception();
}
}
var Agent = {
reception:function(){
// console.log("粉丝送的:"+gift);
let money = new Money();
star.reception(money.total);
}
}
var star = {
reception:function(gift){
console.log("收到粉丝的:"+gift); //收到粉丝的:一百万现金
}
}
Fans.flower();
明星收到一百万后十分开心。由于这笔钱不是鲜花,未触发经纪人的拦截过滤条件,因此明星直接接收了礼物。这种模式称为虚拟代理模式。
虚拟代理实现图片懒加载
在未使用代理模式时,相关代码实现如下:
// 创建一个本体对象
var myImage = (function(){
// 创建标签
var imgNode = document.createElement( 'img' );
// 添加到页面
document.body.appendChild( imgNode );
return {
// 设置图片的src
setSrc: function( src ){
// 更改src
imgNode.src = src;
}
}
})();
myImage.setSrc( 'http:// image.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
虚拟代理
// 创建一个本体对象
var myImage = (function(){
// 创建标签
var imgNode = document.createElement( 'img' );
// 添加到页面
document.body.appendChild( imgNode );
return {
// 设置图片的src
setSrc: function( src ){
// 更改src
imgNode.src = src;
}
}
})();
// 创建代理对象
var proxyImage = (function(){
// 创建一个新的img标签
var img = new Image;
// img 加载完成事件
img.onload = function(){
// 调用 myImage 替换src方法
myImage.setSrc( this.src );
}
return {
// 代理设置地址
setSrc: function( src ){
// 预加载 loading
myImage.setSrc( 'file:// /C:/Users/svenzeng/Desktop/loading.gif' );
// 赋值正常图片地址
img.src = src;
}
}
})();
proxyImage.setSrc( 'http:// image.qq.com/music/photo/k/000GGDys0yA0Nk.jpg' );
上述代码利用代理模式实现了图片预加载功能。通过代理模式,巧妙地将图片创建与预加载逻辑分离。若未来无需预加载功能,只需将请求对象由代理对象替换为本体对象即可。
以上为JavaScript设计模式学习之代理模式的详细内容,更多关于JavaScript设计模式的资料请关注本站其它相关文章!
怎么使用 JavaScript import() 实现模块的条件加载
2026-11-05 14:44:45
前端防御XSS攻击:怎么防止恶意JS注入与CSP策略配置
2026-11-04 08:51:38
怎么解决 Turf.js 处理大规模 GeoJSON 数据的性能瓶颈
2026-11-03 23:22:19
为什么不建议在JS中手动拼接JSON字符串?
2026-11-03 22:48:27
代码混淆对JS执行性能的影响测试与分析
2026-11-03 22:25:37








