JavaScript代理对象

在处理对象时,我们可以创建一个代理对象拦截并更改现有对象的行为。

我们使用代理人本机对象,在ES2015中引入。

假设我们有一个car目的:

const car = {
  color: 'blue'
}

我们可以做的一个非常简单的示例是,当我们尝试访问不存在的属性时返回一个“未找到”字符串。

您可以定义每次尝试访问该对象的属性时都会调用的代理。

您可以通过创建另一个具有get()方法,该方法接收目标对象和属性作为参数:

const car = {
  color: 'blue'
}

const handler = { get(target, property) { return target[property] ?? ‘Not found’ } }

现在我们可以通过调用来初始化代理对象new Proxy(),传递原始对象和我们的处理程序:

const proxyObject = new Proxy(car, handler)

现在尝试访问包含在car对象,但从引用它proxyObject

proxyObject.color //'blue'

就像打电话一样car.color

但是,当您尝试访问不存在的属性时car, 喜欢car.test,你会回来的undefined。使用代理,您将获得'Not found'字符串,因为这就是我们告诉它要做的。

proxyObject.test //'Not found'

我们不仅限于get()代理处理程序中的方法。那只是我们可以写的最简单的例子。

我们还有其他方法可以使用:

  • apply当我们使用时被称为apply()在对象上
  • construct当我们访问对象构造函数时调用
  • deleteProperty当我们尝试删除属性时执行
  • defineProperty当我们在对象上定义新属性时调用
  • set当我们尝试设置属性时执行

等等。基本上,我们可以创建一个受保护的门来控制对象上发生的所有事情,并提供其他规则和控件来实现我们自己的逻辑。

其他方法(也称为陷阱)我们可以使用的是:

  • enumerate
  • getOwnPropertyDescriptor
  • getPrototypeOf
  • has
  • isExtensible
  • ownKeys
  • preventExtensions
  • setPrototypeOf

全部对应于各自的功能。

你可以阅读更多有关MDN上的内容的信息

让我们用另一个例子deleteProperty。我们要防止删除对象的属性:

const car = {
  color: 'blue'
}

const handler = { deleteProperty(target, property) { return false } }

const proxyObject = new Proxy(car, handler)

如果我们打电话delete proxyObject.color,我们将收到TypeError:

TypeError: 'deleteProperty' on proxy: trap returned falsish for property 'color'

Of course one could always delete the property directly on the car object, but if you write your logic so that that object is inaccessible and you only expose the proxy, that is a way to encapsulate your logic.


More js tutorials: