代理模式(Proxy Pattern)是一种设计模式,它为对象提供一个代理,以控制对该对象的访问。可以把代理理解为对象的“中间人”,在访问目标对象时,代理可以拦截操作,并进行处理、修改或限制。在 ES6 中,JavaScript 引入了 Proxy 对象,使得代理模式的实现变得更加简单和强大。
代理模式用法
ES6 引入的 Proxy 对象让我们可以轻松创建代理。new Proxy(target, handler) 接受两个参数:target 是要代理的对象,handler 是一个对象,其中包含了代理的行为。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const target = { name: 'Lanpz', age: 18 }; const handler = { get: function(target, property) { console.log(`访问属性: ${property}`); return target[property]; }, set: function(target, property, value) { console.log(`设置 ${property} 属性为 ${value}`); target[property] = value; } } const proxy = new Proxy(target, handler); proxy.name; proxy.age = 20;
|
在上面的例子中,我们创建了一个代理对象 proxy,它代理了 target 对象。当我们访问 proxy 的属性时,会触发 get 方法,当我们设置 proxy 的属性时,会触发 set 方法。
代理的常见应用场景
1. 数据验证
代理可以用来验证数据的有效性,例如在表单提交时,我们可以使用代理来验证表单数据是否符合要求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| const form = { name: '', age: '' }; const handler = { set: function(target, property, value) { if (property === 'name' && value.length < 2) { throw new Error('姓名长度不能小于2'); } if (property === 'age' && (value < 0 || value > 150)) { throw new Error('年龄必须在0-150之间'); } target[property] = value; } } const proxy = new Proxy(form, handler); proxy.name = 'Lanpz'; proxy.age = 180;
|
2.保护对象属性
代理可以用来保护对象的属性,例如在一个对象中,我们只想暴露部分属性给外部访问,但是不给外部删除和修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const obj = { name: 'Lanpz', age: 18, _password: '123456' }; const handler = { get: function(target, property) { if (property === '_password') { return '******' } return target[property]; }, set: function(target, property, value) { if (property.startsWith('_')) { throw new Error('不能修改以 _ 开头的属性'); } target[property] = value; }, deleteProperty: function(target, property) { if (property.startsWith('_')) { throw new Error('不能删除以 _ 开头的属性'); } delete target[property]; } } const proxy = new Proxy(obj, handler); console.log(proxy.name); proxy.age = 20; console.log(proxy._password); delete proxy._password;
|
- 代理模式会带来一些性能上的开销,尤其是在频繁访问对象属性的场景下,因此在使用时需要权衡利弊。
- 过度使用代理模式可能会导致代码变得难以维护,因此在使用代理模式时需要谨慎。
- 通过代理模式,我们可以在不修改原始对象的情况下,增强对象的行为,实现各种高级功能。