Reflect反射和proxy代理

作者: sweetBoy_9126 | 来源:发表于2019-02-25 16:27 被阅读11次

    Reflect

    • get
      1.获取自己的属性
    var obj = {name: 'fa',age: 18}
    Reflect.get(obj,'name') //'fa'
    
    1. 当前对象里的某个属性设置了get,则可以通过第三个参数改变this,反射到其他函数中
    var obj1 = {a:1,b:2,get c(){return this.a + this.b}}
    var obj2 = {a:3,b:4}
    Reflect.get(obj1,'c',obj2)//7
    
    • set
    1. 修改自己的属性值
    var myObject = {
      foo: 1,
      set bar(value) {
        return this.foo = value;
      },
    }
    
    myObject.foo // 1
    
    Reflect.set(myObject, 'foo', 2);
    myObject.foo // 2
    
    1. 如果属性设置了set,可以通过改变this修改另一个属性的值
    var myObject = {
      foo: 4,
      set bar(value) {
        return this.foo = value;
      },
    };
    
    var myReceiverObject = {
      foo: 0,
    };
    
    Reflect.set(myObject, 'bar', 1, myReceiverObject);
    myObject.foo // 4
    myReceiverObject.foo // 1
    

    proxy代理

    上图中以房屋代理为例,我们找房屋中介,那我们属于被代理的人,房屋中间就属于代理,代理可以根据你的要求为你做过滤筛选

    下面我们对一个对象做读和写的代理

    //被代理对象是一个空对象
    var beiProxy = {}
    var proxy = new Proxy(beiProxy, {
        get: function(target, key){
            console.log('target:')
            console.log(target)
            console.log('key:')
            console.log(key)
    //把你的读取操作反射到这个代理对象上
            return Reflect.get(target,key)
        },
        set: function(target, key, value){
            console.log('target:')
            console.log(target)
            console.log('key:')
            console.log(key)
            console.log('value:')
            console.log(value)
            return Reflect.set(target,key,value)
        }
    }
    

    上面的代码当我们直接获取proxy某个属性的时候会发现不止打印了它的属性,还打印了target什么的,这就说明被代理了

    • 可以对一些属性的值进行过滤
    var game = {
        lives: 3
    }
    var proxy = new Proxy(game, {
        get(target, name){
            return Reflect.get(target, name)
        },
        set(target, name, value){
            //如果你的属性是lives并且值小于0就让它等于0
            if(name === 'lives' && value < 0){
                value = 0
            }
            return Reflect.set(target, name, value)
        }
    })
    proxy.lives = -1
    //-1
    game.lives
    //0
    

    比如我们上面的代码lives是一个游戏里的命数,因为设置命数不可能小于0,所以我们对set进行了过滤后然后反射到被代理对象game,这时候我们如果设置proxy.lives=-1会发现game.lives是0

    但是上面的代码存在一个问题,因为把game这个对象暴露给了用户,用户有可能直接设置game.lives那么我们做的过滤和限制就没用了,这时候我们为了不暴露我们的代理对象,就需要直接在proxy的第一个参数写入这个对象

    var proxy = new Proxy({lives: 3}, {
        get(target, name){
            return Reflect.get(target, name)
        },
        set(target, name, value){
            //如果你的属性是lives并且值小于0就让它等于0
            if(name === 'lives' && value < 0){
                value = 0
            }
            return Reflect.set(target, name, value)
        }
    })
    
    • 实现访问任何不存在的属性都能得到特定的值
    var proxy = new Proxy({}, {
      get: function(target, property) {
        return 35;
      }
    });
    
    proxy.time // 35
    proxy.name // 35
    proxy.title // 35
    

    上面的代码你不管访问什么属性都会得到35

    • proxy代理对象的时候只会代理当前对象,不会代理对象里的子对象
      比如:
    var data = {
      obj: {
        a: 1
      } 
    }
    

    上面的代码只会代理data而不会代理obj,也就是说你代理data时添加的属性都是和obj同一级的

    • 在vue中使用proxy实现响应式
      原理:因为proxy可以对没有的属性进行操作
    var data = {
        obj: {
            name: 'lifa'
        }
    }
    var proxy = new Proxy(data.obj,{
        set: function(target, name, value){
            return Reflect.set(target, name, value)
        }
    })
    

    相关文章

      网友评论

        本文标题:Reflect反射和proxy代理

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