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;

        }

})

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值