当前位置: 首页 > 工具软件 > pbscc-proxy > 使用案例 >

Proxy

屈昊天
2023-12-01

Proxy
Proxy用于修改某些操作的默认行为 ,等同于在语言层面做出修改,所以属于”元编程”,即是对编程语言进行编程。

Proxy可以理解成,在目标对象之前架设一层”拦截”,外界对对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。原意是代理,表示由它来”代理”某些操作。
ES6原生提供Proxy构造函数,用来生成Proxy实例。

var proxy = new Proxy(target, handler);

Proxy对象的所有写法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

拦截读取属性的例子。

var proxy = new Proxy({}, {
  get: function(target, property) {
    return 35;
  }
});

proxy.time // 35
proxy.name // 35
proxy.title // 35

Proxy作为构造函数,接受两个参数。第一个参数是所要代理的目标对象(例子中的空对象),第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操纵。

上面代码中,配置对象有一个get方法,用来拦截对目标对象属性的访问请求。get方法的两个参数分别是目标对象和所要访问的属性。由于拦截函数总是返回35,所以访问任何属性都会得到35。

Proxy实例的方法
get()
get方法用于拦截某个属性的读取操作,可以接受三个参数,依次为目标对象,属性名和proxy实例本身(可选)。

拦截读取操作的例子:

var person = {
  name: "张三"
};

var proxy = new Proxy(person, {
  get: function(target, property) {
    if (property in target) {
      return target[property];
    } else {
      throw new ReferenceError("Property \"" + property + "\" does not exist.");
    }
  }
});

proxy.name // "张三"
proxy.age // 抛出一个错误

上面代码表示, 如果访问目标对象不存在的属性,会抛出一个错误。如果没有这个拦截函数,访问不存在的属性,只会返回undefined。

set()
set方法用来拦截某个属性的赋值操作,可以接受四个参数。依次为目标对象、属性名、属性值和Proxy实例本身(可选)。

假定Person对象有一个age属性,该属性应该是一个不大于200的整数,那么可以使用Proxy保证age的属性值符合要求。

let validator = {
  set: function(obj, prop, value) {
    if (prop === 'age') {
      if (!Number.isInteger(value)) {
        throw new TypeError('The age is not an integer');
      }
      if (value > 200) {
        throw new RangeError('The age seems invalid');
      }
    }

    // 对于满足条件的 age 属性以及其他属性,直接保存
    obj[prop] = value;
  }
};

let person = new Proxy({}, validator);

person.age = 100;

person.age // 100
person.age = 'young' // 报错
person.age = 300 // 报错

上面代码中,由于设置了存值函数set,任何不符合要求的age属性赋值,都会抛出一个错误,这是数据验证的一种实现方法。利用set方法,还可以数据绑定,即每当对象发生变化时,会自动更新DOM。

apply()
apply方法拦截函数的调用、call和apply操作。

apply方法可以接受三个参数,分别是目标对象、目标对象的上下文对象(this)和目标对象的参数数组。

例子:

var target = function () { return 'I am the target'; };
var handler = {
  apply: function () {
    return 'I am the proxy';
  }
};

var p = new Proxy(target, handler);

p()
// "I am the proxy"

上面代码中,变量p是Proxy的实例,当它作为函数调用时p(),就会被apply拦截,返回一个字符串。

 类似资料: