Skip to content

Proxy

代理器: 在目标对象之前架设一层"拦截",外界对该对象的访问,都必须先通过这层拦截 。

1、get()方法

get方法是用于拦截某个属性的读取操作,可以接受三个参数,依次为 target:目标对象;prop:属性名; proxy实例本身 (操作行为所针对的对象),最后一个参数可选

var person ={
  name:"jack"
};
var proxy =new Proxy(person,{
    get: function(target,prop) {
        if(prop in target){
            console.log(target[prop]);
        }else{
            throw new ReferenceError("Prop name \"" + propKey + "\" does not exist.")
        }
    }
})
proxy.name//jack
proxy.age//抛出一个错误

2、 set()方法

set()方法用来拦截某个属性的赋值操作,可以接受四个参数,依次为 target:目标对象;prop:属性名;value:属性值; Proxy 实例本身,其中最后一个参数可选。

var person ={
    name:'john'
};
var proxy =new Proxy(person,{
    set: function(target,prop,value){
        if(prop==='age'){
            if(value>200){
                throw new RangeError('不符合范围')
            }
            else{
                target[prop] = value;
            }
        }
    }
})
proxy.age=400//报错,不继续执行
proxy.age=100//100

3、 apply()方法

pply方法拦截函数的调用

var target = function(){ return 'I am the target'};
var handler = {
  apply: function(){
    return 'i am the proxy';
  }
}
var p = new Proxy(target, handler);
console.log(p());  // "i am the proxy"

4、为什么要存在Proxy?

因为在ES6之前,我们使用Object.defineProperty()来设置监听器,来监听对象属性的获取和改写。但是如果其中存在其他的一些操作,我们是无法监测到的,所以为了解决这样一个问题,在ES6中增加了Proxy代理。Proxy可以帮助我们监听对象中的操作。

  • Object.defineProperty
let info = {
  name: 'dmc',
  age: 20
}

Object.defineProperty(info, 'name', {
  get() {
    console.log('get--获取info的name值')
    return 'dl'
  },
  set() {
    console.log('set--设置info的name值')
  }
})

console.log(info.name) // get--获取info的name值   dl
info.name = 'dmc'  // set--设置info的name值
  • Proxy
let info = {
  name: 'dmc',
  age: 20
}

let infoProxy = new Proxy(info, {
  get(target, key) {
    console.log('获取对象属性')
    return target[key]
  },
  set(target, key, newValue) {
    console.log('设置对象属性')
    target[key] = newValue
  }
})