代理模式(Proxy Pattern)在设计模式中是一种结构型模式,它允许你提供一个替代或占位的对象来控制对另一个对象的访问。在 JavaScript 中,你可以利用 Proxy 对象和反射 API 来创建动态的代理。
在代理模式中,我们通常有以下三个角色:
- Subject(主题) – 被代理的原始对象。
- Proxy(代理) – 是一个包装器,包含对主题对象的引用,并且公开与主题相同的接口。
- Client(客户端) – 与代理对象交互,而不知道底层的主题对象。
使用代理的好处:
- 控制访问:代理可以检查请求并决定是否允许访问。
- 智能引用:代理可以处理缓存、延迟加载等。
- 增强功能:例如,记录日志、性能监控、事务管理等。
在 ES6 中,Proxy
是一种内置对象,可以用来定义基本操作的自定义行为(如属性查找、赋值、枚举等)。以下是创建一个简单代理的例子:通过 proxy
访问和修改属性。当读取 proxy.name
时,控制台会输出 "Getting name"
,因为 get
捕获器被触发了。当尝试设置 proxy.age
时,由于之前 user
对象没有 age
属性,set
捕获器被触发,并输出 "Setting age=27"
。
// 创建一个对象 user,包含一个 name 属性
const user = {
name: 'Jake'
};
// 使用 Proxy 创建一个代理对象 proxy
const proxy = new Proxy(user, {
// 拦截对对象属性的获取操作
get(target, property, receiver) {
console.log(`Getting ${property}`); // 打印正在获取的属性名
return Reflect.get(target, property, receiver); // 使用 Reflect.get 获取属性值
},
// 拦截对对象属性的设置操作
set(target, property, value, receiver) {
console.log(`Setting ${property}=${value}`); // 打印正在设置的属性名和值
return Reflect.set(target, property, value, receiver); // 使用 Reflect.set 设置属性值
}
});
// 访问代理对象的 name 属性
proxy.name; // 控制台输出: Getting name
// 设置代理对象的 age 属性
proxy.age = 27; // 控制台输出: Setting age=27