JS Proxy 的代理对象和目标对象

24 min read

JS Proxy 是一个内置对象,用于创建可进行操作的代理对象。代理对象充当目标对象的拦截器,可以拦截或修改目标对象上的操作。

通过 Proxy 构造函数创建代理对象时,需要传入两个参数:目标对象和一个处理程序(也称为陷阱或拦截器)。目标对象是我们希望拦截的对象,处理程序是一个包含拦截方法的对象,它用于定义代理对象上的操作行为。

代理对象和目标对象之间有以下关系:

  1. 当我们操作代理对象时,代理对象会调用处理程序中对应的拦截方法。
  2. 处理程序可以通过提供自定义逻辑来修改或阻止对目标对象的操作。
  3. 如果处理程序没有提供某个拦截方法,那么操作会直接转发到目标对象上。

代理对象可以拦截目标对象上的各种操作,包括属性的读取、属性的设置、函数调用等。处理程序可以根据需要在拦截方法中进行自定义操作,像是记录日志、验证输入、修改返回结果等。

下面是一个简单的示例,演示了 Proxy 的基本用法:

const target = {
  name: "John",
  age: 30
};

const handler = {
  get: function(target, prop) {
    console.log("Getting property:", prop);
    return target[prop];
  },
  set: function(target, prop, value) {
    console.log("Setting property:", prop);
    target[prop] = value;
  }
};

const proxy = new Proxy(target, handler);

console.log(proxy.name); // 获取属性: name
proxy.age = 35; // 设置属性: age

console.log(target.age); // 35

在此示例中,我们创建了一个目标对象 target,它包含一个 name 属性和一个 age 属性。我们还定义了一个处理程序 handler,其中包含 getset 拦截方法。最后,我们使用这个目标对象和处理程序创建了一个代理对象 proxy。当我们通过代理对象访问属性时,get 拦截方法会被执行,记录一条日志并返回目标对象上对应的属性值。同样地,当我们通过代理对象设置属性时,set 拦截方法会被执行,记录一条日志并设置目标对象上对应的属性值。

实际运行结果:

Getting property: name
John
Setting property: age

可以看到,通过代理对象访问属性时,会自动触发拦截方法中的代码逻辑,并返回对应的属性值。使用代理对象设置属性也会触发拦截方法,并在控制台中打印相关信息。