代理(Proxy)和反射(Reflection)API
代理是一種可以攔截並改變底層javascript引擎操作的包裝器,在新語言中通過它暴露內部運作對象,從而讓開發者可以創建內建的對象。
| 代理陷阱 | 覆寫的特性 | 默認特性 |
|---|---|---|
| get | 讀取一個屬性值 | Reflect.get() |
| set | 寫入一個屬性值 | Reflect.set() |
| has | in操作符 | Reflect.has() |
| deleteProperty | delete操作符 | Reflect.deleteProperty() |
| getPropertyOf | Object.getPropertyOf() | Reflect.getPropertyOf() |
| setPropertyOf | Object.setPropertyOf() | Reflect.setPropertyOf() |
| isExtensible | Object.isExtensible() | Reflect.isExtensible() |
| preventExtensions | Object.preventExtensions() | Reflect.preventExtensions() |
| getOwnPropertyDescriptor | Object.getOwnPropertyDescriptor() | Reflect.getOwnPropertyDescriptor() |
| defineProperty | Object.defineProperty() | Reflect.defineProperty() |
| ownKeys | Object.keys() Object.getOwnPropertyNames() Object.getOwnPropertySymbols() |
Reflect.ownKeys() |
| apply | 調用一個函數 | Reflect.apply() |
| construct | 用new調用一個函數 | Reflect.construct() |
## 創建一個簡單的代理
let target = {}
let proxy = new Proxy(target,{}),
proxy.name = "proxy";
console.log(proxy.name) // proxy
console.log(target.name) // proxy
target.name = "target"
console.log(proxy.name) // target
console.log(target.name) // target
使用set陷阱驗證屬性
接受4個參數
- trapTarget 用於接收屬性(代理的目標) 的對象
- key 要寫入的屬性鍵
- value 被寫入屬性的值
- receiver 操作發生的對象(通常是代理)
let target = {
name:"target"
}
let proxy = new Proxy(target,{
set(trapTarget,key,value,recevier){
// 忽略不希望受到影響的已有屬性
if(!trapTarget.hasOwnProperty(key)){
if(isNaN(value)){
throw new TypeError('屬性必須是數字')
}
}
// 添加屬性
return Reflect.set(trapTarget,key,value,recevier)
}
})
proxy.count = 1;
console.log(proxy.count) // 1
console.log(target.count) // 1
// 由於目標已經有name屬性因而可以給它賦值
proxy.name = "proxy"
console.log(proxy.name) // proxy
console.log(target.name) // proxy
// 給不存在的屬性賦值會拋出錯誤
proxy.otherName = "proxy"
後面的不想看……有空再說吧
主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/4340