• ES6中的代理proxy


    Proxy:代理器,改变对象的默认访问行为;在对象的访问行为之前增设拦截,通过Proxy实例进行的访问行为都必须经过设置的拦截;在拦截中可以根据需要 设置拦截条件

    p()为自定义函数,后文中的p()都是调用这个函数

            let p = function(){
                console.log(...arguments);
            }

    目录

    拦截器

    一、数组代理

    二、对象代理

    三、函数代理

    四、class代理

    五、ES5中的代理


    拦截器

    拦截器作用
    get拦截对象属性的读取,如obj.key,obj['key'],返回属性值
    set拦截属性的设置,返回布尔值
    has拦截key in obj的操作,返回布尔值
    ownKeys

    拦截遍历如:

            for in 循环
            Object.getOwnPropertyNames(obj);
            Object.getOwnPropertySymbols(obj);
            Object.keys(obj);

    一、数组代理

    1、拦截获取值的操作

    2、拦截设置操作,给数组赋值或者添加元素时触发如:arr.push(xxx),arr[0] = xxx

    let arr = [1,2,3,4,5];

    arr = new Proxy(arr,{

            //如果元素存在返回值,否则返回error

            get(target,prop){//target为代理的对象,此处为数组arr;prop此处为索引

                    return prop in target ? target[prop] : 'error';

            },

            //设置值时触发

            set(target,prop,val){

                    if(typeof val === 'number'){//是数值类型添加,否则报错,

                           target[prop] = val;//可根据实际需要修改条件

                            return true;

                    }else return false;

            }

    })

    二、对象代理

    1、拦截是否存在如in

            let age = {
                min:0,
                max:143
            }
            age = new Proxy(age,{
                has(target,prop){
                    return prop >= target.min && prop <= target.max;
                }
            })
            p(23 in age);
            p(144 in age);

    2、拦截遍历如:

            for in 循环
            Object.getOwnPropertyNames(obj);
            Object.getOwnPropertySymbols(obj);
            Object.keys(obj);

            let user = {
                name:"Asia",
                age:23,
                _password:'666'
            }
            user = new Proxy(user,{
                ownKeys(target){

                    //将对象的所有键中以'_'开头的键过滤掉,此处过滤了密码属性
                    return Object.keys(target).filter(key => !key.startsWith('_'));//可根据需要自定义拦截条件
                }
            });
            for(let key in user){
                p(key);
            }

    3、拦截某些属性一切操作

            let u = {
                name:'Asia',
                age:23,
                _password:'666'
            }
            u = new Proxy(u,{
                set(obj,key,val){
                    if(key.startsWith('_')){
                        throw new Error('不可修改');
                    }else{
                        obj[key] = val;
                    }
                },
                get(obj,key){
                    if(key.startsWith('_')){
                        throw new Error('不可访问');
                    }else{
                        return obj[key];
                    }
                },
                deleteProperty(obj,key){
                    if(key.startsWith('_')){
                        throw new Error('不可删除');
                    }else{
                        delete obj[key];
                        return true;
                    }
                },
                ownKeys(obj,key){
                    return Object.keys(obj).filter(key => !key.startsWith('_'));
                }
            })
            
            try{
                u._password = '000';
            }catch(err){
                p(err.message);
            };
            
            try{
                p(u._password);
            }catch(err){
                p(err.message);
            }
            
            try{
                delete u._password;
                
            }catch(err){
                p(err.message);
            }
            Object.keys(u).forEach(key => p(u[key])); 

    三、函数代理

    改变函数返回值

            let sum = (...args) => {
                let sum = 0;
                args.forEach(item => {
                    sum += item;
                });
                return sum;
            }
            sum = new Proxy(sum,{
                apply(fn,ctx,args){
                    return fn(...args) * 10;
                }
            });
            p(sum(1,2,3));//60
            p(sum.call(null,1,2,3));//60
            p(sum.apply(null,[1,2,3]));//60

    四、class代理

    对new进行拦截

    let User = class{
                constructor(name){
                    this.name = name;
                }
            }
            User = new Proxy(User,{
                construct(cls,args,newCls){
                    p('construct 正在拦截');
                    return new cls(...args);
                }
            });
            p(new User('Asia'));

    五、ES5中的代理

    Object.definePrototype(obj,属性名,callback);

    let obj = {};

    let _name = '';

    Object.definePrototype(obj,'name',{

            set(val){

                    _name = val;

            },

            get(){

                    return _name;

            }

    })

  • 相关阅读:
    关系数据库与文档数据库对比
    Docker使用总结
    uniapp获取公钥、MD5,‘keytool‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    金九银十,收下这份 Java String 面试题
    2020南京icpc M 树形背包
    Springboot登录验证的统一拦截处理
    jsbarcode生成条码
    项目:点餐系统
    从SmartPay dll学到的内容 宏定义 单件模式 迭代 日志记录函数进入与出来
    漏洞简述-漏洞分析实例是编号CVE-2006-3439
  • 原文地址:https://blog.csdn.net/SignalFire/article/details/125536375