Proxy
Proxy 对象用于定义基本操作的自定义行为
语法
const p = new Proxy(target, handler)
参数
target
要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler
一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。
handler 对象的方法
handler 对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy 的各个捕获器(trap)。
所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。
1、handler.get() 属性读取操作的捕捉器。
语法
let p = new Proxy(target, {
get (target, property, receiver) {
console.log(target, property, receiver)
}
});
参数
target
目标对象。
property
被获取的属性名。
receiver
Proxy或者继承Proxy的对象
示例
let person = {
name: 'Bob',
age: 18
}
person = new Proxy(person, {
get (target, key, r) {
console.log(target, key, r)
return target[key]
}
})
console.log(person.name)
// target {name: "Bob", age: 18}
// key "name"
// r Proxy {name: "Bob", age: 18}
2、handler.set() 属性设置操作的捕捉器。
语法
const p = new Proxy(target, {
set (target, property, value, receiver) {
console.log(target, property, value, receiver)
}
});
参数
target
目标对象。
property
将被设置的属性名或 Symbol。
value
新属性值。
receiver
最初被调用的对象。
示例
let person = {
name: 'Bob',
age: 18
}
person = new Proxy(person, {
get (target, key, r) {
return target[key]
},
set (target, property, value, receiver) {
console.log(target, property, value, receiver)
target[property] = value
}
})
person.name = 'Alice'
console.log(person.name)
// target {name: "Bob", age: 18}
// property "name"
// value "Alice"
// receiver Proxy {name: "Bob", age: 18}
// person.name Alice
返回值
set() 方法应当返回一个布尔值。
- 返回 true 代表属性设置成功。
- 在严格模式下,如果 set() 方法返回 false,那么会抛出一个 TypeError 异常。
3、handler.defineProperty() Object.defineProperty 方法的捕捉器。
语法
const p = new Proxy(target, {
defineProperty (target, property, descriptor) {
console.log(target, property, descriptor)
}
})
参数
target
目标对象。
property
待检索其描述的属性名。
descriptor
待定义或修改的属性的描述符。
返回值
defineProperty 方法必须以一个 Boolean 返回,表示定义该属性的操作成功与否。
示例
let person = {
name: 'Bob',
age: 18
}
person = new Proxy(person, {
defineProperty (target, property, descriptor) {
console.log(target, property, descriptor)
target[property] = descriptor
return true
}
})
let desc = { configurable: true, enumerable: true, value: 10 };
Object.defineProperty(person, 'a', desc)
console.log(person)
// target {name: "Bob", age: 18}
// property "a"
// descriptor {value: 10, enumerable: true, configurable: true}
// person Proxy {name: "Bob", age: 18, a: {…}}
proxy 数组方法
let arr = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 3, b: 2}, {a: 4, b: 2}]
arr = new Proxy(arr, {
defineProperty(t, p, desc) {
console.log(t, p, desc)
Reflect.set(t, p, desc.value)
return true
}
})
// 能触发 handler defineProperty 方法
arr.push()
arr.pop()
arr.reverse()
...
4、handler.deleteProperty() delete 操作符的捕捉器。
语法
var p = new Proxy(target, {
deleteProperty (target, property) {
}
});
参数
target
目标对象。
property
待删除的属性名。
示例
let cat = {pz: 'bos', age: 2, animal: 'Cat'}
cat = new Proxy(cat, {
deleteProperty (target, property) {
console.log(target, property)
Reflect.deleteProperty(target, property)
}
})
delete cat.pz
console.log(cat)
// target {pz: "bos", age: 2, animal: "Cat"}
// property "pz"
// cat Proxy {age: 2, animal: "Cat"}
5、handler.has() in 操作符的捕捉器。
语法
var p = new Proxy(target, {
has (target, prop) {
}
});
参数
target
目标对象.
prop
需要检查是否存在的属性.
示例
let cat = {pz: 'bos', age: 2, animal: 'Cat'}
cat = new Proxy(cat, {
has (target, property) {
console.log(target, property)
return Reflect.has(target, property)
}
})
console.log('pz' in cat)
// target {pz: "bos", age: 2, animal: "Cat"}
// property "pz"
// true
6、handler.ownKeys() Object.getOwnPropertyNames 方法和 Object.getOwnPropertySymbols 方法的捕捉器。
语法
let p = new Proxy(target, {
ownKeys (target) {
}
})
参数
target
目标对象.
示例
let a = Symbol()
let cat = {pz: 'bos', age: 2, animal: 'Cat'}
cat[a] = 'this is symbol value'
cat = new Proxy(cat, {
ownKeys (target) {
console.log(target)
return Reflect.ownKeys(target)
}
})
console.log(Object.getOwnPropertyNames(cat))
console.log(Object.getOwnPropertySymbols(cat))
// target {pz: "bos", age: 2, animal: "Cat", Symbol(): "this is symbol value"}
// ["pz", "age", "animal"]
// [Symbol()]