有几种不同的JS操作会调用同一个捕获器处理程序。不过,对于在代理对象上执行的任何一种操作,只会有一个捕获处理程序被调用。不会存在重复捕获的情况。
get()
obj.get(property)获取对象属性
get()捕获器会在获取属性值的操作中被调用
对应的反射API方法为Reflect.get()
const myTarget = {};
const proxy = new Proxy(myTarget, {
get(target, property, receiver) {
return Relect.get(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象property:引用的目标对象上的字符串键属性receiver:代理对象或继承代理对象的对象
-
返回值
不限
-
拦截的操作
proxy.propertyproxy[property]Object.create(proxy)[property]Reflect.get(proxy, property, receiver)
-
捕获器不变式
如果
target.property不可写且不可配置,则处理程序返回的值必须与target.property匹配如果
target.property不可配置且[[Get]]特性为undefined,处理程序的返回值也必须是undefined
set()
obj.key = val;对象属性赋值
set()捕获器会再设置属性值的操作中被调用
对应的反射API方法为Reflect.set()
const myTarget = {};
const proxy = new Proxy(myTarget, {
set(target, property, value, receiver) {
return Reflect.set(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象property:引用的目标对象的字符串键属性value:要赋给属性的值receiver:接收最初赋值的对象
-
返回值
true表示成功;false表示失败,严格模式下会抛出TypeError -
拦截的操作
proxy.property = valueproxy[property] = valueObject.create(proxy)[property] = valueReflect.set(proxy, property, value, receiver)
-
捕获器不变式
如果
target.property不可写且不可配置,则不能修改目标属性的值如果
target.property不可配置且[[Set]]特性为undefined,则不能修改目标属性的值在严格模式下,处理程序中返回
false会抛出TypeError
has()
obj.has(property)判断对象中是否有某属性
has()捕获器会在in操作符中被调用
对应的反射API方法为Reflect.has()
const myTarget = {};
const proxy = new Proxy(myTarget, {
has(target, property) {
return Reflect.has(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象property:引用的目标对象上的字符串键属性
-
返回值
has()必须返回布尔值,表示属性是否存在。 -
拦截的操作
property in proxyproperty in Object.create(proxy)with(proxy) {(property)}Reflect.has(proxy, property)
-
捕获器不变式
如果
target.property存在且不可配置,则处理程序必须返回true如果
target.property存在且目标对象不可扩展,则处理程序必须返回true
defineProperty()
obj.defineProperty(target, key, {..})为某对象设置属性
此捕获器会在Object.defineProperty()中被调用
对应的反射API方法为Reflect.defineProperty()
const myTarget = {};
const proxy = new Proxy(myTarget, {
defineProperty(target, property, descriptor) {
return Reflect.defineProperty(...arguments);
}
})
Object.defineProperty(proxy, 'foo', { value: 'bar' })
-
捕获器处理程序参数
target:目标对象property:引用的目标对象上的字符串键属性descriptor:包含可选地enumerable、configurable、writable、value、get和set定义的对象
-
返回值
必须返回布尔值,表示属性是否成功定义
-
拦截的操作
Object.defineProperty(proxy, property, descriptor)Reflect.defineProperty(proxy, property, descriptor)
-
捕获器不变式
如果目标对象不可扩展,则无法定义属性
如果目标对象有一个可配置的属性,则不能添加同名的不可配置属性
如果目标对象有一个不可配置的属性,则不能添加同名的可配置属性
getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(obj, property)读取对象中某个属性的特性
getOwnPropertyDescriptor()捕获器会在Object.getOwnPropertyDescriptor()中被调用。
对应的反射API方法为Reflect.getOwnPropertyDescriptor()
const myTarget = {};
const proxy = new Proxy(myTarget, {
getOwnPropertyDescriptor(target, property) {
return Reflect.getOwnPropertyDescriptor(...arguments);
}
});
Object.getOwnPropertyDescriptor(proxy, 'foo');
-
捕获器处理程序参数
target:目标对象property:引用的目标对象上的字符串键属性
-
返回值
必须返回对象,或者在属性不存在时返回
undefined -
拦截的操作
Object.getOwnPropertyDescriptor(proxy, property)Reflect.getOwnPropertyDescriptor(proxy, property)
-
捕获器不变式
如果自有的
target.property存在且不可配置,则处理程序必须返回一个表示该属性存在的对象如果自有的
target.property存在且可配置,则处理程序必须返回表示该属性可配置的对象如果自有的
target.property存在且target不可扩展,则处理程序必须返回一个表示该属性存在的对象如果
target.property不存在且target不可扩展,则处理程序必须返回undefined表示该属性不存在如果
target.property不存在,则处理程序不能返回表示该属性可配置的对象
deleteProperty()
delete obj.key删除对象中某个属性
deleteProperty()捕获器在delete操作中被调用
对应的反射API方法为Reflect.deleteProperty()
const myTarget = {};
const proxy = new Proxy(myTarget, {
deleteProperty(target, property) {
return Reflect.deleteProperty(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象property: 引用的目标对象上的字符串键属性
-
返回值
必须返回布尔值,表示删除属性是否成功。
-
拦截的操作
delete proxy.propertydelete proxy[property]Reflect.deleteProperty(proxy, property)
-
捕获器不变式
如果自有的
target.property存在且不可配置,则处理程序不能删除这个属性
ownKeys()
Object.keys(obj)获取对象中自有属性
ownKeys()捕获器在Object.keys()及类似方法中被调用
对应的反射API方法为Reflect.ownKeys()
const myTarget = {};
const proxy = new Proxy(myTarget, {
ownKeys(target) {
return Reflect.ownKeys(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象
-
返回值
必须返回包含字符串或符号的可枚举对象
-
拦截的操作
Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)Reflect.ownKeys(proxy)
-
捕获器不变式
返回的可枚举对象必须包含
target的所有不可配置的自有属性如果
target不可扩展,则返回可枚举对象必须准确的包含自有属性键。
getPrototypeOf()
obj.__proto__获取对象的原型(内部[[Prototype]]属性的值)
getPrototypeOf()捕获器在Object.getPrototypeOf()中被调用。
对应的反射API方法为Reflect.getPrototypeOf()
const myTarget = {};
const proxy = new Proxy(myTarget, {
getPrototypeOf(target) {
return Reflect.getPrototypeOf(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象
-
返回值
必须返回对象或
null -
拦截的操作
Object.getPrototypeOf(proxy)Reflect.getPrototypeOf(proxy)proxy.__proto__Object.prototype.isPrototypeOf(proxy)proxy instanceof Object
-
捕获器不变式
如果
target不可扩展,则Object.getPrototypeOf(proxy)唯一有效的返回值就是Object.getPrototypeOf(target)的返回值
setPrototypeOf()
Object.setPrototypeOf(obj, prototype)设置对象的原型
setPrototypeOf()捕获器在Object.setPrototypeOf()中被调用。
对应的反射API方法为Reflect.setPrototypeOf()
const myTarget = {};
const proxy = new Proxy(myTarget, {
setPrototypeOf(target, prototype) {
return Reflect.setPrototypeOf(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象prototype:target的替代原型,如果是顶级原型则为null
-
返回值
必须返回布尔值,表示原型赋值是否成功。
-
拦截的操作
Object.setPrototypeOf(proxy)Reflect.setPrototypeOf(proxy)
-
捕获器不变式
如果
target不可扩展,则唯一有效的prototype参数就是Object.getPrototypeOf(target)的返回值
isExtensible()
Object.isExtensible(obj)判断一个对象是否是可扩展的
isExtensible()捕获器会在Object.isExtensible()中被调用。
对应的反射API方法为Reflect.isExtensible()
const myTarget = {};
const proxy = new proxy(myTarget, {
isExtensible(target) {
return Reflect.isExtensible(...arguments);
}
})
-
捕获器处理程序参数
target:目标对象
-
返回值
必须返回布尔值,表示
target是否可扩展 -
拦截的操作
Object.isExtensible(proxy)Reflect.isExtensible(proxy)
-
捕获器不变式
如果
target可扩展,则处理程序必须返回true如果
target不可扩展,则处理程序必须返回false
preventExtensions()
Object.preventExtensions(obj)让对象变的不可扩展
preventExtensions()捕获器会在Object.preventExtensions()中被调用
对应的反射API方法为Reflect.preventExtensions()
const myTarget = {};
const proxy = new Proxy(myTarget, {
preventExtensions(target) {
return Reflect.preventExtensions(...arguments)
}
})
-
捕获器处理程序参数
target:目标对象
-
返回值
必须返回布尔值,表示
target是否已经不可扩展 -
拦截的操作
Object.preventExtensions(proxy)Reflect.preventExtensions(proxy)
-
捕获器不变式
如果
Object.isExtensible(proxy)是false,则处理程序必须返回true
apply()
fun.apply(this)修改this指向
apply()捕获器在调用函数时被调用
对应的反射API方法为Reflect.apply()
const myTarget = () => {};
const proxy = new Proxy(myTarget, {
apply(target, thisArg, ...argumentsList) {
return Reflect.apply(...arguments);
}
});
-
捕获器处理程序参数
target:目标对象thisArg:调用函数时的this参数argumentsList: 调用函数时的参数列表
-
返回值
无限制
-
拦截的操作
proxy(...argumentsList)Function.prototype.apply(thisArg, argumentsList)Function.prototype.call(thisArg, ...argumentsList)Reflect.apply(target, thisArgument, argumentsList)
-
捕获器不变式
target必须是一个函数对象
construct()
const obj = new ConstructorFun()实例化构造函数
construct()捕获器会在new操作符中被调用。
对应的反射API方法为Reflect.construct()
const proxy = new Proxy(myTarget, {
construct(target, argumentsList, newTarget) {
return Reflect.construct(...arguments)
}
});
-
捕获器处理程序参数
target: 目标构造函数argumentsList:传给目标构造函数的参数列表newTarget:最初被调用的构造函数
-
返回值
必须是一个对象
-
拦截的操作
new proxy(...argumentsList)Reflect.construct(target, argumentsList, newTarget)
-
捕获器不变式
target必须可以用作构造函数