Js代理和反射的常见用途

本文介绍了JavaScript中的代理模式,通过代理可以实现属性访问跟踪、隐藏属性、属性验证、函数参数验证以及事件分派等功能。例如,代理可用于在设置属性时进行类型检查,或者在数组操作后触发自定义事件。这增强了代码的可控性和安全性。
摘要由CSDN通过智能技术生成

// 代理模式的一些有用编程方式

1:跟踪属性访问


        const user = {
            name: 'jack'
        };
        const proxy = new Proxy(user, {
            get(target, property, receiver) {
                console.log(`getting ${property}`);
                return Reflect.get(...arguments)
            },
            set(target, property, value, receiver) {
                console.log(`setting ${property}=${value}`);
                return Reflect.set(...arguments)
            }
        });
        proxy.name;//getting name
        proxy.age = 25;//setting age=25

2:隐藏属性,代理的内部实现对外部代码是不可见得,因此要隐藏目标对象上的属性也是轻而易举的

        const hiddenProperties = ['foo', 'bar'];
        const targetObj = {
            foo: 1,
            bar: 2,
            baz: 3
        }
        const proxy = new Proxy(targetObj, {
            get(target, property) {
                if (hiddenProperties.includes(property)) {
                    return undefined
                }
                else {
                    return Reflect.get(...arguments)
                }
            },
            has(target, property) {
                if (hiddenProperties.includes(property)) {
                    return false
                }
                else {
                    return Reflect.has(...arguments)
                }
            }
        })
        console.log(proxy.foo);//undefined
        console.log(proxy.bar);//undefined
        console.log(proxy.baz);//3

        console.log('foo' in proxy);//false
        console.log('bar' in proxy);//false
        console.log('baz' in proxy);//true

3:属性验证

        const target = {
            onlyNumbersGoHere: 0
        };
        const proxy = new Proxy(target, {
            set(target, property, value) {
                if (typeof value !== 'number') {
                    return false
                }
                else {
                    return Reflect.set(...arguments)
                }
            }
        })
        proxy.onlyNumbersGoHere = 1;
        console.log(proxy.onlyNumbersGoHere);//1
        proxy.onlyNumbersGoHere = '2';
        console.log(proxy.onlyNumbersGoHere);//1

4:函数和构造函数参数验证

        const median = function (...nums) {
            return nums.sort()[Math.floor(nums.length / 2)]
        }
        const proxy = new Proxy(median, {
            apply(target, thisArg, argumentsList) {
                for (const arg of argumentsList) {
                    if (typeof arg !== 'number') {
                        throw 'Non-number argument provided'
                    }
                }
                return Reflect.apply(...arguments)
            }
        })
        console.log(proxy(1, 3, 6));//3
        console.log(proxy(1, '3', 6));//Non-number argument provided

5:使用事件分派程序,每次插入新实例都会发送信息

        const userList = [];
        function emit(newValue) {
            console.log(newValue)
        }
        const proxy = new Proxy(userList, {
            set(target, property, value, receiver) {
                const result = Reflect.set(...arguments);
                if (result) {
                    emit(Reflect.get(target, property, receiver))
                }
                return result
            }
        });
        proxy.push("john");//john //1  使用数组方法改变元素后,会把当前length传进去触发set
        proxy[1] = 'tom';//tom
        
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值