JS每日一題:如何理解es6中的Proxy?

febobo發表於2019-02-16

20190124問:

如何理解es6中的Proxy?

試題解析:對proxy的理解,可能會延伸到vue的雙向繫結

Proxy(代理) 定義

可以理解為為目標物件架設一層攔截,外界對該物件的訪問,都必須通過這層攔截

簡單示例:

 const obj = new Proxy({}, {
     get: (target, key, receiver) => {
         return `JS`
         console.log(`get ${key}`)
     },
     set: (target, key, value, receiver) => {
         console.log(`set ${key}`)
     },
 })
 
 obj.name = `JS 每日一題` 
 // set name
 // JS 每日一題
 
 obj.name 
 // 這裡進入get的回撥函式,所有直接返回 JS 

從上面的示例中可以看出,Proxy存在一種機制,可以對外界的讀寫操作進行改寫

Proxy 例項方法

proxy除了代理get,set操作,還能代理其它的操作,如下

handler.getPrototypeOf()

// 在讀取代理物件的原型時觸發該操作,比如在執行 Object.getPrototypeOf(proxy) 時。

handler.setPrototypeOf()

// 在設定代理物件的原型時觸發該操作,比如在執行 Object.setPrototypeOf(proxy, null) 時。

handler.isExtensible()

// 在判斷一個代理物件是否是可擴充套件時觸發該操作,比如在執行 Object.isExtensible(proxy) 時。

handler.preventExtensions()

// 在讓一個代理物件不可擴充套件時觸發該操作,比如在執行 Object.preventExtensions(proxy) 時。

handler.getOwnPropertyDescriptor()

// 在獲取代理物件某個屬性的屬性描述時觸發該操作,比如在執行 Object.getOwnPropertyDescriptor(proxy, "foo") 時。

handler.defineProperty()

// 在定義代理物件某個屬性時的屬性描述時觸發該操作,比如在執行 Object.defineProperty(proxy, "foo", {}) 時。

handler.has()

// 在判斷代理物件是否擁有某個屬性時觸發該操作,比如在執行 "foo" in proxy 時。

handler.get()

// 在讀取代理物件的某個屬性時觸發該操作,比如在執行 proxy.foo 時。

handler.set()

// 在給代理物件的某個屬性賦值時觸發該操作,比如在執行 proxy.foo = 1 時。

handler.deleteProperty()

// 在刪除代理物件的某個屬性時觸發該操作,比如在執行 delete proxy.foo 時。

handler.ownKeys()

// 在獲取代理物件的所有屬性鍵時觸發該操作,比如在執行 Object.getOwnPropertyNames(proxy) 時。

handler.apply()

// 在呼叫一個目標物件為函式的代理物件時觸發該操作,比如在執行 proxy() 時。

handler.construct()

// 在給一個目標物件為建構函式的代理物件構造例項時觸發該操作,比如在執行new proxy() 時。

為什麼要使用Proxy

  • 攔截和監視外部對物件的訪問
  • 降低函式或類的複雜度
  • 在複雜操作前對操作進行校驗或對所需資源進行管理

題外思考

如何用proxy實現雙向繫結?

往期

JS每日一題: 前端的快取有哪些?都適用什麼場景?區別是什麼?
JS每日一題: Call,Apply,Bind的使用與區別,如何實現一個bind?
JS每日一題: 說說你對前端模組化的理解
JS每日一題: web安全攻擊手段有哪些?以及如何防範

關於JS每日一題

JS每日一題可以看成是一個語音答題社群
每天利用碎片時間採用60秒內的語音形式來完成當天的考題
群主在次日0點推送當天的參考答案

  • 注 絕不僅限於完成當天任務,更多是查漏補缺,學習群內其它同學優秀的答題思路

點選加入答題

相關文章