ES6 Proxy的學習與理解

問題

前一段時間在字節跳動時聊到了Proxy。起因是問道Vue中數據綁定的實現,回答通過設置setter和getter實現,問這樣有什麼缺點,答在對對象的屬性的監控方面存在瑕疵,例如通過直接設置數組下標進行賦值,或者對對象直接進行修改,是無法觀察到的,必須使用Vue.set添加,或者使用Array.prototype.push等方法。
面試官介紹說在Vue3中已經通過Proxy解決了這個問題。Proxy是ES6中添加的內置對象,和Reflect配合功能十分強大。正好今天看到一個問題

理解

根據MDN的文檔,Proxy是對原對象的包裝。可以包裝的內容包括一系列get、set等,值得注意的是getPrototypeOf同樣是一種可以攔截的操作。同時,對於未定義的操作保持原結果。
在instanceof的頁面,可以看到如下示例

function C() {}
function D() {}

var o = new C();

// true, because: Object.getPrototypeOf(o) === C.prototype
o instanceof C;

那麼,在上面那個問題中,既然未定義proxy的getPrototypeOf,那它就該與原對象保持一致。使用以下代碼進行驗證:

Object.getPrototypeOf(proxy) === Array.prototype //true

進一步思考

那麼,是不是對於一切行爲,在不做任何攔截的情況下,就能保證與目標對象的行爲完全一致呢?很顯然,這是不可能的。例如

a = {}
b = new Proxy(a, {})
console.log(a === b) //false

以及this的指向問題(案例來自阮一峯文章

const target = {
  m: function () {
    console.log(this === proxy);
  }
};
const handler = {};

const proxy = new Proxy(target, handler);

target.m() // false
proxy.m()  // true

雖然大部分情況下這應該不會成爲大的障礙,但遇到錯誤的時候可以從這裏入手尋找問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章