Proxy
Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)
target
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
handler.get()
属性读取操作的捕捉器。
handler.set()
属性设置操作的捕捉器。
let p = {
name: 'aa'
}
p.name; // 取值
p.name='xxx' // 赋值
let proxy = new Proxy(p, {
get() {
},
//赋值
// p name xxx p
set(target, key, value, receiver) {
return true;
}
})
Reflect
Reflect对象一共有 13 个静态方法。
- Reflect.apply(target, thisArg, args)
- Reflect.construct(target, args)
- Reflect.get(target, name, receiver)
- Reflect.set(target, name, value, receiver)
- Reflect.defineProperty(target, name, desc)
- Reflect.deleteProperty(target, name)
- Reflect.has(target, name)
- Reflect.ownKeys(target)
- Reflect.isExtensible(target)
- Reflect.preventExtensions(target)
- Reflect.getOwnPropertyDescriptor(target, name)
- Reflect.getPrototypeOf(target)
- Reflect.setPrototypeOf(target, prototype)
上面这些方法的作用,大部分与Object对象的同名方法的作用都是相同的,而且它与Proxy对象的方法是一一对应的。
示例
Proxy+Reflect结合
- Reflect.get(target, name, receiver)
let p = {
name: 'aa',
age:20
}
let proxy = new Proxy(p, {
get(target, key, receiver) {
if(target.age<=18){
return Reflect.get(target, key, receiver)
}else{
return '大于18哈哈'
}
},
set(target, key, value, receiver) {
return true;
}
})
console.log(proxy.age); // 大于18哈哈
- Reflect.set(target, name, value, receiver)
let p = {
name: 'aa',
age: 20
}
Reflect.set(p, 'name', 'bb', p);
console.log(p.name); // bb
案例简单实现一个mobx观察者模式
let list: Set<Function> = new Set();
let autorun = (cb: Function) => {
if (cb) {
list.add(cb);
}
}
const observable = <T extends object>(parms: T) => {
return new Proxy(parms, {
set(target, key, value, receiver) {
list.forEach((cb: Function) => cb())
return Reflect.set(target, key, value, receiver)
}
})
}
let p = observable({ name: 'zl', age: 18 })
autorun(() => {
console.log('哈哈,有变化了');
})
p.age=20