理解ES6中的代理与反射(Proxy)

概述

es6新增的代理和反射为开发者提供了拦截并向基本操作嵌入额外行为的能力。具体的来说,就是在对目标对象的各种操作影像目标对象之前,可以在代理对象中对这些操作加以控制。




提示:以下是本篇文章正文内容,下面案例可供参考

一、创建空代理?

        const target = {
            name: "yang",
        };
        const handler = {};
        const proxy = new Proxy(target, handler)

        // name属性会访问同一个值
        console.log(target.name); // 'yang'
        console.log(proxy.name); // 'yang'

        // 给目标对象属性赋值会反映在两个对象上
        // 因为两个对象访问的是同一个值
        target.name = 't8';
        console.log(target.name); // 't8'
        console.log(proxy.name); // 't8'

        // 给代理属性赋值会反映在两个对象上
        // 因为这个赋值会转移到目标对象
        proxy.name = 't9';
        console.log(target.name); // 't9'
        console.log(proxy.name); // 't9'

        console.log(target.hasOwnProperty('name')); // true
        console.log(proxy.hasOwnProperty('name')); // true

        // Proxy.prototype是undefined
        console.log(target instanceof Proxy);
        console.log(proxy instanceof Proxy);
        // Uncaught TypeError: Function has non-object prototype 'undefined' in instanceof check

        // 严格相等可以用来区分代理和目标
        console.log(target === proxy) // false

二、定义捕获器

        const target = {
            name: "yang",
        };
        const handler = {
            get() {
                return 'handler override'
            }
        };
        const proxy = new Proxy(target, handler)
        console.log(target.name) // 'yang'
        console.log(proxy.name) // 'handler override'

三、捕获器参数和反射API

所有捕获器都可以访问相应的参数,基于这些参数可以重建被捕获方法的原始行为。get()捕获器会接收到目标对象、要查询的属性和代理对象三个参数。

        const target = {
            name: "yang",
        };
        const handler = {
            get(target, key, receiver) {
                return '经过代理' + target[key] + '代理完毕';
            },
        };
        const proxy = new Proxy(target, handler)
        console.log(target.name) // 'yang'
        console.log(proxy.name) // '经过代理yang代理完毕'

开发者并不需要手动重建原始行为,而是可以通过调用全局Reflect对象(封装了原始行为)的同名方法来重建。

        const target = {
            name: "yang",
        };
        const handler = {
            get(target, key, receiver) {
                // let res = Reflect.get(target, key, receiver);
                let res = Reflect.get(...arguments);
                return '经过代理' + res + '代理完毕';
            },
        };
        const proxy = new Proxy(target, handler)
        console.log(target.name) // 'yang'
        console.log(proxy.name) // '经过代理yang代理完毕'

四、可撤销代理

有时候可能需要中断代理对象与目标对象之间的联系。对于使用new Proxy()创建的普通代理来说,这种联系会在代理对象的生命周期内一直持续存在。
Proxy也暴露了revocable()方法,这个方法支持撤销代理对象与目标对象之间的关联,撤销代理的操作是不可逆的。撤销代理之后在调用代理会抛出TypeError。

 const target = {
            name: "yang",
        };
        const handler = {
            get(target, key, receiver) {
                return 'intercepted';
            },
        };
        const { proxy, revoke } = Proxy.revocable(target, handler)
        console.log(target.name) // 'yang'
        console.log(proxy.name) // 'intercepted'

        revoke()
        console.log(proxy.name) // 'Uncaught TypeError: Cannot perform 'get' on a proxy that has been revoked'

总结

这是对Porxy的一些基础概念和基本api做出的一些总结,如果对你有帮助,帮忙点个赞吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值