代理(Proxy)和反射(Reflection)API

// 代理(Proxy)和反射(Reflection)
        

        // 代理直接将所有操作直接转发到目标,将“proxy”赋值给proxy.name属性时会在目标上建立name,
        // 代理只是简单的将操作转发给目标,他不会存储这个属性。由于proxy.name 和 target.name 引用的
        // 都是 target.name 因此二者值相同
        /*let target = {};
        let proxy = new Proxy(target, {});

        proxy.name = "proxy";
        console.log(proxy.name);
        console.log(target.name);

        target.name = "target";
        console.log(proxy.name);
        console.log(target.name);*/


        // 使用set陷阱验证属性
        // 1. trapTarget 用于接收属性(代理的目标) 的对象
        // 2. key  要写入的属性键(字符串或symbol类型)
        // 3. value  被写入的属性的值
        // 4. receiver  操作发生的对象 (通常是代理)
        
        /*let target = {
            name : "target"
        };

        let proxy = new Proxy(target, {
            set(trapTarget, key, value, receiver) {
                // 忽略已有属性
                if(!trapTarget.hasOwnProperty(key)){
                    // 验证属性值 必须为数字
                    if(isNaN(value)){
                        throw new TypeError("属性必须是数字");
                    }
                }

                // 添加属性
                return Reflect.set(trapTraget, key, value, receiver);
            }
        });


        proxy.count = 1;
        console.log(proxy.count);  // 1
        console.log(target.count); // 1
        // 这是因为属性值 是数字 所以可以添加count属性到target上
        
        // 由于已有的name属性 因而可以直接给他赋值
        proxy.name = "proxy";
        console.log(proxy.name); // “proxy"
        console.log(target.name); // "proxy"

        proxy.anotherName = " wujiahui ";  // 会抛出错误 因为属性值是非数字*/

 

        // 用get 陷阱验证对象结构(Object Shape)
        // 1. trapTarget 被读取属性的源对象 (代理的目标)
        // 2. key 要读取的属性键 (字符串或symbol)
        // 3. receiver 操作发生的对象 (通常是代理)
        
       /* let proxy = new Proxy({}. {
            get(trapTarget, key, receiver) {
                if(!(key in receiver)) {
                    throw new TypeError("属性" + key + "不存在");
                }

                return Reflect.get(trapTraget, key, recevier);
            }
        });

        // 如果属性不存在会抛出错误 (对比在对象中 属性不存在抛出 undefined)
        console.log(proxy.name); // 抛出错误 */

 

        // 属性描述符陷阱
        // defineProperty 陷阱接收以下参数
        // 1. trapTarget  要定义属性的对象
        // 2. key  属性的键 (字符串或symbol)
        // 3. descriptor  属性的描述符对象

        
        /*let proxy = new Proxy({}, {
            defineProperty(tarpTarget, key, descriptor) {
                return Reflect.defineProperty(trapTarget, key, descriptor);
            },
            getOwnPropertyDescriptor(trapTarget, key) {
                return Reflect.getOwnPropertyDescriptor(trapTarget, key);
            }
        });

        Object.defineProperty(proxy, "name", {
            value: "Proxy"
        });

        console.log(proxy.name);  // "proxy"

        let descriptor = Object.getOwnPropertyDescriptor(proxy, name);

        console.log(descriptor.value); // "proxy"*/

 

        // 函数代理中的apply 和 construct陷阱
        
        // Reflect.construct 和 Reflect.apply 接收以下参数
        // 1. trapTarget  被执行的函数(代理的目标)
        // 2. thisArg  函数被调用时内部this的值
        // 3. argumentsList 传递给函数的参数数组
        //  当使用new调用函数时调用的construct 陷阱接收以下参数
        //  1. trapTarget  被执行的函数(代理的目标)
        //  2. argumentsList 传递给函数的参数数组

        /* let target = function() { return 42; },
            proxy = new Proxy(target, {
                apply: function(trapTarget, thisArg, argumentsList) {
                    return Reflect.apply(trapTarget, thisArg, argumentsList);
                },
                construct: function(trapTarget, argumentsList) {
                    return Reflect.construct(trapTarget, argumentsList);
                }
            });


            // 一个目标是函数的代理看起来也像一个函数
            console.log(typeof proxy);      // "function"


            console.log(proxy());          // 42


            var instance = new proxy();
            console.log(instance instanceof proxy);   // true
            console.log(instance instanceof target);  // true
        */
        /*在这里,有一个返回数字42的函数,该函数的代理分别使用apply陷阱和construct陷阱来
           将那些行为委托给Reflect.apply()方法和Reflect.construct()方法。最终结果是代理函数
           与目标函数完全相同,包括在使用typeof时将自己标识为函数。不用new调用代理时返回42,
           用new调用时创建一个instance对象,它同时是代理和目标的实例,因为instanceof通过原型
           链来确认此信息。而原型链查找不受代理影响。这也就是代理和目标好像有相同原型的原因。
        */
    

        //  检测数组索引
        //  当且仅当ToString(ToUnit32(p)) 等于p,并且ToUnit32(p)不等于2^32 -1 ,字符串属性名称
        //  p才是一个数组的索引

        
        /*    function toUnit32(value) {
            return Math.floor(Math.abs(Number(value))) % Math.pow(2, 32);
        }

        function isArrayIndex(key) {
            let numerickey = toUnit32(key);
            return String(numerickey) == key && numerickey < (Math.pow(2, 32) -1 );
        }*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值