一文教你了解代理

130 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 9 天,点击查看活动详情

代理基础

ES6 新增的代理与反射为开发者提供了拦截并向基本操作嵌入额外行为的能力。具体地说,可以给目标对象定义一个关联的代理对象,而这个代理对象可以作为抽象的目标对象来使用。在对目标对象的各种操作影响目标对象之前,可以在代理对象中对这些操作加以控制。

代理是目标对象的抽象。从很多方面来看,代理类似 C++指针,因为它可以用作目标对象的替身,但又完全独立于目标对象。目标对象既可以直接被操作,也可以通过代理来操作。但直接操作会绕过代理施予的行为。

创建代理

最简单的代理是空代理,即除了作为一个抽象目标的对象,上面也不做。默认情况下,在代理对象上执行的所有操作都会无障碍地传播到目标对象。因此,在任何可以使用目标对象的地方,都可以通过同样的方式来与之关联的代理操作。

代理是使用 Proxy 构造函数创建的。这个构造函数接收两个参数:目标对象和处理程序对象。缺少其中任何一个参数都会抛出 TypeError。要创建空代理,可以传入一个简单的对象字面量作为处理成序对象。从而让所有操作畅通无阻地抵达目标对象。

//创建原始对象
const target = {
  id: "target",
};

const handler = {};
// 获取代理
const proxy = new Proxy(target, handler);

//id属性会访问同一个对象
console.log(proxy.id); //target
console.log(target.id); //target

//给两个对象修改id属性,两个对象都会改变
proxy.id = "foo";
target.id = "foo";

console.log(proxy.id); //foo
console.log(target.id); //foo

//都拥有hasOwnProperty方法

console.log(proxy.hasOwnProperty("id")); //true
console.log(target.hasOwnProperty("id")); //true

//Proxy.prototype是undefined,因此无法使用instanceof操作符
console.log(proxy instanceof Proxy); //false
console.log(target instanceof Proxy); //false

//严格相等可以区别proxy和target
console.log(proxy === target); //false