学习proxy对象代理

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)

target

要使用 ​​Proxy​​ 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler

一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 ​​p​​ 的行为。

​handler.get()​​ 本次使用的get

属性读取操作的捕捉器。

​handler.set()​​ 本次使用的set

属性设置操作的捕捉器。

Reflect

与大多数全局对象不同​​Reflect​​​并非一个构造函数,所以不能通过​​new运算符​​​对其进行调用,或者将​​Reflect​​​对象作为一个函数来调用。​​Reflect​​​的所有属性和方法都是静态的(就像​​Math​​对象)

Reflect.get(target, name, receiver) 

​Reflect.get​​​方法查找并返回​​target​​​对象的​​name​​属性,如果没有该属性返回undefined

Reflect.set(target, name,value, receiver) 

​Reflect.set​​​方法设置​​target​​​对象的​​name​​​属性等于​​value​​。

type Person = {
name: string,
age: number,
text: string
}


const proxy = (object: any, key: any) => {
return new Proxy(object, {
get(target, prop, receiver) {
console.log(`get key======>${key}`);
return Reflect.get(target, prop, receiver)
},

set(target, prop, value, receiver) {
console.log(`set key======>${key}`);

return Reflect.set(target, prop, value, receiver)
}
})
}

const logAccess = (object: Person, key: 'name' | 'age' | 'text') => {
return proxy(object, key)
}

let man: Person = logAccess({
name: "小满",
age: 20,
text: "我的很小"
}, 'age')

man.age = 30

console.log(man);

使用泛型+keyof优化

type Person = {
name: string,
age: number,
text: string
}


const proxy = (object: any, key: any) => {
return new Proxy(object, {
get(target, prop, receiver) {
console.log(`get key======>${key}`);
return Reflect.get(target, prop, receiver)
},

set(target, prop, value, receiver) {
console.log(`set key======>${key}`);

return Reflect.set(target, prop, value, receiver)
}
})
}


const logAccess = <T>(object: T, key: keyof T): T => {
return proxy(object, key)
}

let man: Person = logAccess({
name: "小满",
age: 20,
text: "我的很小"
}, 'age')


let man2 = logAccess({
id:1,
name:"小满2"
}, 'name')

man.age = 30

console.log(man);