美文网首页
代理相关学习

代理相关学习

作者: 怀念小兔 | 来源:发表于2019-01-24 16:42 被阅读3次

    代理(Proxy)是ES6中新增的用法,它可以拦截一个对象属性或方法的调用及赋值。
    创建代理的方式如下:

    let proxy = new Proxy(target, handler);
    

    其中target代表要代理的对象,handler描述了拦截后的行为。
    我们首先创建一个对象:

                let sylvilagus = {
                    name: "sylvilagus",
                    type: "rabbit",
                    age: 3,
                    jump: function(){
                        console.log(this.name + " is jumping");
                    }
                };
    

    对它进行一些赋值和打印属性值的操作:

                console.log("name = " + sylvilagus.name);
                console.log("age = " + sylvilagus.age);
                sylvilagus.jump();
    

    发现可以正常输出预期的结果:


    输出了预期结果

    现在,我们想添加一个验证,age必须是数字,那么如果在要求不更改原对象的前提下,我们就可以通过代理来完成它:

                let handler = {
                    set: function(target, key, value){
                        if(key == "age" && isNaN(value)){
                            console.log("error! the value of property age must be a number!");
                            return;
                        }
                        target[key] = value;
                    }
                };
                let proxy = new Proxy(sylvilagus, handler);
                proxy.age = "abc";
    

    执行程序,可以看到控制台输出了我们的拦截提示


    设置非数字年龄失败

    上面是拦截对象属性的赋值,同样的,读取也可以通过代理来拦截:

                    get: function(target, key){
                        return "wrapped" + target[key];
                    }
    

    我们拦截了对象属性的读取,让他在原值的基础上加上wrapped前缀,然后输出它的属性值,并且调用它的jump方法:

                console.log("name = " + proxy.name);
                proxy.jump();
    

    执行程序,控制台输出了结果:

    输出结果
    我们看到,属性的读取得到了我们的预期结果,但方法调用就悲剧了。这是为什么呢?控制台打印一下proxy.jump 注意:不加括号 ,可以发现我们刚才拦截的属性读取影响了它,它也多了个wrapped前缀,影响了方法调用,去掉我们在get中加前缀的逻辑,再次执行程序,发现结果正常。
    代理相关的东西暂时先记录这些,它还能拦截方法调用、构造器调用(new)等很多操作,后续有时间的时候再补充,对我而言,暂时知道es6有代理和反射即可,需要时再深入学习。

    相关文章

      网友评论

          本文标题:代理相关学习

          本文链接:https://www.haomeiwen.com/subject/uzqujqtx.html