JS设计模式-代理模式
JS设计模式大合集
仓库地址:JS设计模式大合集
欢迎大家 Star ,一起交流学习!
代理模式
代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问。我们可以举一个形象的例子:
小明的妈妈想要去买水果,但是有事情忙不开,所以叫小明帮忙去买水果。小明出去之后,他可能会先到玩具店逛一下,然后去水果店逛一下,最后把买到的水果带回家。小明在这个过程中,就相当于代理,他代替妈妈买了水果,但是在买水果的过程中,又可以做一些其他的事情。
代理模式的应用场景
有了代理之后,我们能做的事情可就多了。
比如我们日常前端开发过程中使用到的网络请求拦截axios。
1 |
|
比如我们经常在vite
开发中对域名的代理:
1 | // vite.config.js |
再比如我们大名鼎鼎的VUE的响应式原理proxy
和Object.defineProperty
。(😂关于defineProperty
感兴趣的同学可以去看一下我之前写的文章:vue源码阅读-Object.defineProperty)
1 | const targetObject = { |
代理模式的优缺点
优点
- 代理模式能够将代理对象与真实被调用的目标对象分离。
- 一定程度上降低了系统的耦合度,扩展性好。
- 可以起到保护目标对象的作用。
- 可以对目标对象的功能进行扩展。
缺点
- 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
- 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
倘若无proxy
在js中怎么代理?
在ES6引入Proxy
对象之前,JavaScript中的代理模式通常通过以下几种方式实现:
对象封装:
通过创建一个封装了原始对象的新对象。这个新对象(代理)提供了一个接口,这个接口与原始对象的接口相同,但会添加额外的逻辑,如访问控制、日志记录等。1
2
3
4
5
6
7
8
9
10function createProxy(subject) {
const origMethod = subject.someMethod;
subject.someMethod = function() {
// 额外逻辑
console.log('someMethod was called');
// 调用原始方法
return origMethod.apply(subject, arguments);
};
return subject;
}函数拦截:
使用高阶函数来拦截函数调用。可以在函数前后添加额外的行为,并且能够控制是否调用原始函数。1
2
3
4
5
6
7
8function createFunctionProxy(originalFunction) {
return function() {
// 额外逻辑
console.log('Function was called with arguments:', arguments);
// 调用原始函数
return originalFunction.apply(this, arguments);
};
}发布/订阅模式:
虽然这不是传统的代理模式,但在某些情况下可以起到类似代理的作用。对象不直接调用方法,而是发布一个事件,而另一个对象订阅这个事件并在触发时执行操作。(感兴趣可以去翻一下我之前的文章:JS设计模式-发布订阅者模式,这里我就不贴代码啦~)访问器属性:
使用getter和setter可以在对象属性被访问或修改时执行特定逻辑。这在某种程度上能够模拟属性级别的代理行为。1
2
3
4
5
6
7
8
9
10
11
12
13const obj = {
_a: 1,
get a() {
// 额外逻辑
console.log('a was accessed');
return this._a;
},
set a(value) {
// 额外逻辑
console.log('a was set to', value);
this._a = value;
}
};
总结
在JavaScript的世界里,代理模式展现了其独有的魅力,通过在目标对象和访问者之间引入一个代理层,它不仅为我们提供了一条灵活控制和增强对象行为的途径,而且也极大地丰富了我们对设计模式在现代Web开发中运用的理解和深度。从简单的事件处理到复杂的系统监控,代理模式都能以其独到的方式,帮助我们构建更加高效和可维护的应用系统。