代理(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