共计 2125 个字符,预计需要花费 6 分钟才能阅读完成。
代理模式在 javascript 中能够应用 Proxy 对象,能够更好的去管制一些对象的交互,既然谈到了 Proxy,咱们先简略理解一下 Proxy 到底是干什么的
Proxy
Proxy 是用来创立一个对象的代理,实现对对象的拦挡。比方对象属性的查找、赋值、枚举、函数调用等操作。语法如下
const p = new Proxy(target, handler) | |
// target 要代理的指标对象 | |
// handler 对象,对象中定义了对 target 操作时要执行的一些操作 |
根底应用事例
const handler = {get: function(obj, prop) {return prop in obj ? obj[prop] : 'FE 情报局' | |
} | |
} | |
const target = {} | |
const p = new Proxy(target, handler) | |
p.a = 1 | |
p.b = undefined | |
console.log(p.a, p.b) // 1, undefined | |
console.log('c' in p, p.c) // false, FE 情报局 |
原来的 target 上也有对应的属性 a 和 b,然而要留神,从 target 取值的时候并没有走代理,也就是 target.c 为 undefined,target.a 等于 1
这样咱们能够通过代理来对对象取值进行辨别,比方对于一些不存在的属性,在取值的时候返回 null
代理模式
其实 Proxy 就是一个代理模式,代理的是一个指标对象,下面的例子也表明它能够将对象的变动做一层代理,任何操作都须要通过此代理做一些额定的操作
你能够将其设想成咱们的抓包工具,网络申请进来或者收回都要通过抓包,对其进行一些批改或者解决再给到服务器或者客户端,这种也被称为代理模式
例子
这种模式在咱们的我的项目中具体有什么作用呢?下面咱们提到了,能够将不存在的属性设置为 null
const handler = {get: function(obj, prop) {return prop in obj ? obj[prop] : null | |
} | |
} | |
const target = {} | |
const p = new Proxy(target, handler) | |
// p.a => null |
数据验证
代理也可能帮咱们进行数据验证,可能让指标对象中的数据放弃纯正,不会有一些意外的状况
const handler = {set: function(obj, prop, value) {if(prop === 'age' && value > 0 && value < 100){obj['age'] = value | |
return true | |
}else{throw new Error('age 的值不符合要求,无奈批改') | |
} | |
} | |
} | |
const target = {age: 10} | |
const p = new Proxy(target, handler) | |
// p.a => null |
断点调试
针对一些有问题的数据,你能够进行一些断点或者 log 的操作,来看何时何地将什么内容设置为谬误的数据
const handler = {set: function(obj, prop, value) {console.log(`set ${prop} from ${obj[prop]} to ${value}`); | |
obj[prop] = value; | |
return true | |
} | |
} | |
const target = {} | |
const p = new Proxy(target, handler) | |
p.a = 1 | |
p.a = 2 | |
// set a from undefined to 1 | |
// set a from 1 to 2 |
格式化数据
const handler = {set: function(obj, prop, value) {obj[prop] = Number(value); | |
return true | |
} | |
} | |
const target = {} | |
const p = new Proxy(target, handler) | |
p.age = '10' | |
// p.age => 10 |
扩大对象办法
target 能够是任何一个对象,包含数组,所以咱们能够通过属性查找数组中的内容
const handler = {get: function(obj, prop, value) {if(prop in obj){return obj[prop] | |
} | |
let result = null | |
for(let item of obj){if(item.value === prop){result = item} | |
} | |
if(result){return result} | |
return undefined | |
} | |
} | |
const target = [ | |
{ | |
label: '苹果', | |
value: 'apple' | |
}, | |
{ | |
label: '香蕉', | |
value: 'banana' | |
} | |
] | |
const p = new Proxy(target, handler) | |
// p.length => 2 | |
// p.apple => {label: '苹果', value: 'apple'} | |
// p[0] => {label: '苹果', value: 'apple'} |
总结
代理的确可能不便咱们一些操作,并且制订一些通用的 handler 可能解决咱们很多的问题,然而任何货色都要有一个适度,适度应用代理的形式很容易对利用的性能造成肯定的影响,所以对于一些要害的代码最好不要应用代理
代理还有一点就是在你排查问题的时候可能会有些艰难,比方设置的某一个值不合乎你的预期,或者应用的某一个值也不合乎你的预期,然而你却不晓得你在哪里改了它