ES6入门---第三单元 模块七: Proxy的使用+Reflect的使用

proxy:  代理
    扩展(增强)对象、方法(函数)一些功能

    比如: 
        Vue

        Vue.config.keyCodes.enter=65

    Proxy作用: 比如vue中拦截
        预警、上报、扩展功能、统计、增强对象等等

    proxy是设计模式一种,  代理模式

 


语法:
    new Proxy(target, handler);
    let obj = new Proxy(被代理的对象,对代理的对象做什么操作)

handler:

    {
        set(){},  //设置的时候干的事情
        get(){},  //获取干的事情
        deleteProperty(){},  //删除
        has(){}  //问你有没有这个东西  ‘xxx’ in obj
        apply()  //调用函数处理
        .....
    }


  let obj = {
            name:'Strive'
        };

        let newObj = new Proxy(obj,{//代理obj
            get(target, property){//property 属性 get是获取信息
                //console.log(target, property);
                //TODO
                console.log(`您访问了${property}属性`);
                return target[property];//没有return返回值会都出现undefined
            }
        });

        console.log(newObj.name);


实现一个,访问一个对象身上属性,默认不存在的时候给了undefined,希望如果不存在错误(警告)信息:

  let newObj = new Proxy(obj, {
            get(target, property){
                if(property in target){
                    return target[property];
                }else{
                    //throw new ReferenceError(`${property}属性不在此对象上`);
                    console.warn(`${property}属性不在此对象上`);
                    return '^_^';//替换了出现的undefined
                }
            }
        });


DOM.div()
DOM.a();
DOM.ul()

例:

 <script>
        const DOM = new Proxy({},{
            get(target, property){
                //console.log(target, property);
                //property就是DOM.xxx 里面的xxx
                return function(attr={}, ...children){//json的内容,其他内容
                    //console.log(attr, children);
                    const el = document.createElement(property);

                    //添加属性
                    for(let key of Object.keys(attr)){
                        el.setAttribute(key, attr[key]);
                    }
                    //添加子元素
                    for(let child of children){
                        if(typeof child == 'string'){
                            child = document.createTextNode(child);//创建文本节点
                        }
                        el.appendChild(child);//添加
                    }
                    return el;
                }
            }
        });

        let oDiv = DOM.div({id:'div1',class:'aaa'},'我是div','呵呵呵');//json,内容,……

        console.log(oDiv);
    </script>
  const DOM = new Proxy({},{
            get(target, property){
                //console.log(target, property);
                //property DOM.xxx 里面的xxx
                return function(attr={}, ...children){
                    //console.log(attr, children);
                    const el = document.createElement(property);

                    //添加属性
                    for(let key of Object.keys(attr)){
                        el.setAttribute(key, attr[key]);
                    }
                    //添加子元素
                    for(let child of children){
                        if(typeof child == 'string'){
                            child = document.createTextNode(child);
                        }
                        el.appendChild(child);
                    }
                    return el;
                }
            }
        });

        let oDiv = DOM.div(
            {id:'div1',class:'aaa'},'我是div','呵呵呵',
            DOM.a({href:'http://www.51mmr.net'}, '访问官网'),
            DOM.ul({},
                DOM.li({},'1111'),
                DOM.li({},'2222'),
                DOM.li({},'3333'),
                DOM.li({},'4444')
            )
        );

        window.onload=function(){
            document.body.appendChild(oDiv);
        };

set(), 设置,拦截:
    设置一个年龄,保证是整数,且范围不能超过200

  let obj =new Proxy({},{
            set(target, prop, value){
                if(prop == 'age'){
                    if(!Number.isInteger(value)){
                        throw new TypeError(`年龄必须为整数`);
                    }
                    if(value>200){
                        throw new RangeError('年龄超标了,必须小于200岁');
                    }
                }
                target[prop]=value; 
            }
        });

        obj.a=123;
        obj.name = 'Strive';
        
        console.log(obj);

        obj.age = 201;

deleteProperty(): 删除,拦截:

  let json = {
            a:1,
            b:2
        };

        let newJson = new Proxy(json, {
            deleteProperty(target, property){
                console.log(`您要删除${property}属性`);
                //TODO
                delete target[property];
            }
        });

        delete newJson.a;

        console.log(newJson);


has(): 检测有没有

 let newJson = new Proxy(json, {
            deleteProperty(target, property){
                console.log(`您要删除${property}属性`);
                //TODO
                delete target[property];
            },
            has(target, property){
                console.log(`判断是否存在调用has方法`);
                //TODO
                return property in target;
            }
        });

        console.log('a' in newJson);

apply(target,context指向,args参数数组)  :拦截方法

 function fn(){
            return '我是函数';
        }

        let newFn = new Proxy(fn, {
            apply(){
                return '函数么?';
            }
        });

        console.log(newFn());


Reflect: 反射

将Object.xxx  语言内部方法如:Object.defineProperty放到Reflect对象身上

通过Reflect对象身上直接拿到语言内部东西

比如:


    'assign' in Object    ->   Reflect.has(Object, 'assign')

    delete json.a        ->   Reflect.deleteProperty(json, 'a');

  let json ={a:1, b:2};

        /* delete json.a;

        console.log(json); */

        Reflect.deleteProperty(json, 'a');

        console.log(json);


 


Reflect.apply(调用的函数,this指向,参数数组);与fn.call()    fn.apply()  作用类似

  let res = Reflect.apply(Math.ceil,null, [9.8]);//变形式调用函数

        console.log(res);
  function show(...args){
            console.log(this);
            console.log(args);
        }

        //show(1,2,3,4);

        //show.call('abc', 1,2,3,4);将this改变成abc
        //show.apply('abcd',[1,2,3,4]);

        Reflect.apply(show, 'aaaa', [1,2,3,4]);

 

 function sum(a,b){
            return a+b;
        }

        let newSum = new Proxy(sum, {
            apply(target, context, args){
                //console.log(target, context, args);
                //console.log(...arguments);
                return Reflect.apply(...arguments);
            }
        });

        console.log(newSum(2,3))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值