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: