学习TypeScript23(TS进阶用法proxy & Reflect)

学习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);

 

案例简单实现一个mobx观察者模式

const list: Set<Function> = new Set()

const autorun = (cb: Function) => {
    if (cb) {
        list.add(cb)
    }
}

const observable = <T extends object>(params: T) => {
    return new Proxy(params, {
        set(target, key, value, receiver) {
            const result = Reflect.set(target, key, value, receiver)
            list.forEach(fn => fn())
            console.log(list)
            return result
        }
    })
}

const person = observable({ name: "小满", attr: "威猛先生" })

autorun(()=>{
    console.log('我变化了')
})

person.attr = '威猛个捶捶'

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小满zs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值