学习ts(十二)Proxy与Reflect

定义

Proxy

  • 为开发者提供了拦截并向基本操作嵌入额外行为的能力。具体的说,可以给目标对象定义一个关联的代理对象,而这个代理对象可以作为抽象的目标对象来使用。在对目标对象的各种操作影响目标对象之前,可以在代理对象中对这些操作加以控制。
  • 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于中“元编程”,即对编程语言进行编译。可以理解成在目标对象前架设一个“拦截”层,外界对该对象的访问都必须先通过这层拦截。
  • 通过调用new Prosy(),你可以创建一个代理用来替代另一个对象,这个代理对目标对象进行了虚拟,因此该代理与该目标对象表面上可以被当做同一个对象来对待。

关键词

  • 创建:代理对象是一个新对象
  • 其他对象:只能代理对象

Reflect

  • 将object对象的一些明显属于语言内部的方法(比如:Object.defineProperty)放到Reflect上。现阶段,某些方法同时在Object和Reflect上部署,未来的新方法只会在Reflect上部署。从Reflect可以拿到语言内部的方法。
  • 修改某些方法的返回值,让其变得合理
  • Reflect对象的方法与Proxy对象的方法一一对应

方法

Reflect.get(target,name,receiver)
查找并返回targetname属性,没有则返回undefined

Reflect.set(target,name,value,receiver)
对象属性的设置,返回一个布尔值

Reflect.has(target,propKey)
propKey in proxy 操作,返回一个boolean值

Reflect.deleteProperty(target,name)
等同于delete obj[name],用于删除对象属性

Reflect.construct(target,args)
等同于new target(...args),这提供了一种不使用new来调用构造函数的方法

Reflect.getPrototypeOf(target)
用于读取对象的__proto__属性,对应Object.getPrototypeOf(obj)

Reflect.setPrototypeOf(target,prototype)
用于设置目标对象的原型(prototype),对应Object.setPrototypeOf(obj,newProto)方法,返回一个boolean值,表示是否设置成功

Reflect.apply(target,thisArg,args)
等同于Function.prototype.apply.call(func,thisArg,args),用于绑定this对象后执行给定函数

Reflect.defineProperty(target,name,desc)
方法基本等同于Object,defineProperty,用来为对象定义属性,未来,后者会被逐渐替代

Reflect.getOwnPropertyDescriptor(target,name)
基本等同于Object.getOwnPropertyDescriptor,用于得到指定属性的描述对象,将来会替代掉后者

Reflect.isExtensible
对应Object.isExtensible,返回一个布尔值,表示当前对象是否可扩展。

Reflect.preventExtensions
对应Object.preventExtensions方法,用于让一个对象变为不可扩展。它返回一个布尔值,表示是否操作成功。

Reflect.ownKeys
方法用于返回对象的所有属性,基本等同于Object.getOwnPropertyNamesObject.getOwnPropertySymbols之和

数组倒序访问

var arr = [1, 2, 3, 4]
var proxy = new Proxy(arr, {
    get(target, propKey, receiver) {
        let nPropKey = parseInt(propKey as string) //解析字符串,返回整数
        if (nPropKey < 0) {
            if (Math.abs(nPropKey) <= target.length) { // 返回绝对值
                return target[target.length + nPropKey]
            } else {
                return '访问越界'
            }
        }
        return Reflect.get(target, propKey, receiver)
    }
})
console.log(proxy[-2])
console.log(proxy[-20])

实现观察者模式

const queuedObserverList:Set<Function> = new Set()
const observe = (fn:Function) => {
    queuedObserverList.add(fn)
}
const observable = (obj) => new Proxy(obj, {
    set(target, key, value, receiver) {
        queuedObserverList.forEach((fun) => fun())
        return Reflect.set(target, key, value, receiver)
    }
})

const person = observable({ name: 'hello', age: 11 })
function print() {
    console.log(`${person.name}--${person.age}`)
}
observe(print)
person.name = 'hi'

keyof优化

module A {

    type Person = {
        name: string,
        age: number,
        sex: number
    }
    const proxy = (object: any, key: any) => {
        return new Proxy(object, {
            get(target, prop, receiver) {
                console.log('get')
                return Reflect.get(target, prop, receiver)
            },
            set(target, prop, value, receiver) {
                console.log('set')
                return Reflect.set(target, prop, value, receiver)
            }
        })
    }

    // const logAccess = (object: Person, key: 'name' | 'age' | 'sex') => {
    //     return proxy(object, key)
    // }
    const logAccess = <T>(object: T, key: keyof T) => {
        return proxy(object, key)
    }

    let woman: Person = logAccess({
        name: 'orange',
        sex: 0,
        age: 18
    }, 'age')
    woman.age = 16
    console.log(woman)
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!关于"vue3proxy结合reflect"的问题,我理解你可能想了解如何在Vue 3中使用Proxy与Reflect结合起来。Vue 3是一个流行的JavaScript框架,而Proxy和Reflect则是ES6中新增的特性。 在Vue 3中,可以使用Proxy对象来代理Vue实例,以便捕获对数据的访问和修改。Proxy对象可以拦截并处理对Vue实例的操作,比如读取、设置和删除属性等。而Reflect对象提供了一组用于操作对象的方法,比如Reflect.get()、Reflect.set()和Reflect.deleteProperty()等。 结合使用Proxy和Reflect可以提供更灵活的控制和监控能力。你可以通过在Vue实例上创建一个代理对象,来拦截对数据的访问和修改,并在代理处理器中使用Reflect方法来操作实际的数据。这样可以轻松地实现对数据的拦截、校验、代理等功能。 下面是一个简单的示例代码,展示了如何在Vue 3中使用Proxy和Reflect结合起来: ```javascript const data = { message: 'Hello, Vue!', }; const proxy = new Proxy(data, { get(target, key) { console.log('Getting ' + key); return Reflect.get(target, key); }, set(target, key, value) { console.log('Setting ' + key + ' to ' + value); return Reflect.set(target, key, value); }, }); // 创建Vue应用 const app = Vue.createApp({ data() { return proxy; // 使用代理对象 }, }); app.mount('#app'); ``` 在上面的代码中,我们创建了一个名为data的普通对象,并使用Proxy对象创建了一个代理对象proxy。在代理对象的get和set处理器中,我们分别使用Reflect.get和Reflect.set来操作实际的数据。这样,当我们通过Vue实例访问或修改数据时,会触发代理处理器,并通过Reflect方法操作实际的数据。 希望这个例子能帮助到你,如果还有其他问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值