Proxy
Proxy 可以理解成,在目標對象之前架設一層“攔截”,外界對該對象的訪問,都必須先通過這層攔截,因此提供了一種機制,可以對外界的訪問進行過濾和改寫。Proxy 這個詞的原意是代理,用在這裏表示由它來“代理”某些操作,可以譯爲“代理器”。
// 創建proxy的方法
var proxy = new Proxy(target, handler);
要使這些攔截其效果,都要通過proxy調用,而不是target調用。
proxy的實例方法
- get方法用於攔截某個屬性的讀取操作,可以接受三個參數,依次爲目標對象、屬性名和 proxy 實例本身。
- set方法用來攔截某個屬性的賦值操作,可以接受四個參數,依次爲目標對象、屬性名、屬性值和 Proxy 實例本身
- apply方法攔截函數的調用、call和apply操作。apply方法可以接受三個參數,分別是目標對象、目標對象的上下文對象(this)和目標對象的參數數組。
- has方法用來攔截HasProperty操作,即判斷對象是否具有某個屬性時,這個方法會生效。
- construct方法用於攔截new命令,下面是攔截對象的寫法。
- deleteProperty方法用於攔截delete操作,如果這個方法拋出錯誤或者返回false,當前屬性就無法被delete命令刪除。
- defineProperty方法攔截了Object.defineProperty操作。
- getOwnPropertyDescriptor方法攔截Object.getOwnPropertyDescriptor(),返回一個屬性描述對象或者undefined。
- getPrototypeOf方法主要用來攔截獲取對象原型。
還有其他的很多實例方法。參考 Proxy
。
Proxy.revocable()
Proxy.revocable方法返回一個可取消的 Proxy 實例。
let target = {};
let handler = {};
let {proxy, revoke} = Proxy.revocable(target, handler);
proxy.foo = 123;
proxy.foo // 123
revoke();
proxy.foo // TypeError: Revoked
this 問題
雖然 Proxy 可以代理針對目標對象的訪問,但它不是目標對象的透明代理,即不做任何攔截的情況下,也無法保證與目標對象的行爲一致。主要原因就是在 Proxy 代理的情況下,目標對象內部的this關鍵字會指向 Proxy 代理。
const target = {
m: function () {
console.log(this === proxy);
}
};
const handler = {};
const proxy = new Proxy(target, handler);
target.m() // false
proxy.m() // true