代理模式的定義:為其他對象提供一種代理以控制對這個對象的訪問宛官。在某些情況下滑燃,一個對象不適合或者不能直接引用另一個對象嵌削,而代理對象可以在客戶端和目標(biāo)對象之間起到中介的作用蚣驼。
Proxy
在ES6中新增了一個API叫Proxy羔砾,Proxy 對象用于定義基本操作的自定義行為(如屬性查找负间,賦值,枚舉蜒茄,函數(shù)調(diào)用等)唉擂。
比較抽象,我用一句話總結(jié)就是:Proxy可以覆蓋原有的方法檀葛,實現(xiàn)自定義的默認(rèn)方法的功能玩祟。
基礎(chǔ)語法
let p = new Proxy(target, handler);
/**
* target
* 用Proxy包裝的目標(biāo)對象(可以是任何類型的對象,包括原生數(shù)組屿聋,函數(shù)空扎,甚至另一個代理)
* 一個對象,其屬性是當(dāng)執(zhí)行一個操作時定義代理的行為的函數(shù)
**/
還是用一段代碼來演示一下吧
let person = {
name: 'Tom',
age: 18
}
let newP = new Proxy(person, {
get(target, prop) {
if(!(prop in target)) {
return '沒有對應(yīng)的屬性'
}
return target[prop]
}
})
console.log(person.name) // Tom
console.log(person.age) // 18
console.log(person.amount) // undefined
console.log(newP.name) // Tom
console.log(newP.age) // 18
console.log(newP.amount) // 沒有對應(yīng)的屬性
通過以上代碼润讥,可以看到當(dāng)訪問newP對象中的屬性時转锈,實際上是調(diào)用了自定義的get方法,就是說我們自定義了一個get方法覆蓋了原用的get方法楚殿。
Proxy的Handler
在Proxy中可以使用到的handler方法如下
handler.getPrototypeOf()
在讀取代理對象的原型時觸發(fā)該操作撮慨,比如在執(zhí)行 Object.getPrototypeOf(proxy) 時。
handler.setPrototypeOf()
在設(shè)置代理對象的原型時觸發(fā)該操作脆粥,比如在執(zhí)行 Object.setPrototypeOf(proxy, null) 時砌溺。
handler.isExtensible()
在判斷一個代理對象是否是可擴展時觸發(fā)該操作,比如在執(zhí)行 Object.isExtensible(proxy) 時变隔。
handler.preventExtensions()
在讓一個代理對象不可擴展時觸發(fā)該操作规伐,比如在執(zhí)行 Object.preventExtensions(proxy) 時。
handler.getOwnPropertyDescriptor()
在獲取代理對象某個屬性的屬性描述時觸發(fā)該操作匣缘,比如在執(zhí)行 Object.getOwnPropertyDescriptor(proxy, "foo") 時猖闪。
handler.defineProperty()
在定義代理對象某個屬性時的屬性描述時觸發(fā)該操作,比如在執(zhí)行 Object.defineProperty(proxy, "foo", {}) 時肌厨。
handler.has()
在判斷代理對象是否擁有某個屬性時觸發(fā)該操作培慌,比如在執(zhí)行 "foo" in proxy 時。
handler.get()
在讀取代理對象的某個屬性時觸發(fā)該操作柑爸,比如在執(zhí)行 proxy.foo 時检柬。
handler.set()
在給代理對象的某個屬性賦值時觸發(fā)該操作,比如在執(zhí)行 proxy.foo = 1 時。
handler.deleteProperty()
在刪除代理對象的某個屬性時觸發(fā)該操作何址,即使用 delete 運算符里逆,比如在執(zhí)行 delete proxy.foo 時。
handler.ownKeys()
Object.getOwnPropertyNames 和Object.getOwnPropertySymbols 的陷阱用爪。
handler.apply()
函數(shù)調(diào)用操作的陷阱原押。
handler.construct()
new 運算符的陷阱。
Proxy的兼容性
參考
MDN