捕获器
一、handler.apply()
**handler.apply()
方法用于拦截函数的调用。target
**必须是可被调用的。也就是说,它必须是一个函数对象。
1.1 语法
const proxy = new Proxy(target, {
apply(target, thisArg, argumentsList) {
}
});
-
target
: 目标对象(函数)。target
必须是可被调用的。也就是说,它必须是一个函数对象。 -
thisArg
: 被调用时的上下文对象 -
argumentsList
: 被调用时的参数数组
1.2 返回值
apply
方法可以返回任何值。
1.3 拦截场景
拦截proxy(...args)
const proxy = new Proxy(function(){},{
apply:function(target,thisArg,argumentsList){
console.log(argumentsList.join(','));
}
});
proxy('a','b','c');
拦截Reflect.apply()
拦截Function.prototype.apply()
或者Function.prototype.call()
应用场景
- 通过 handler 捕获函数的调用
二、handler.construct()
handler.construct()
方法用于拦截new
操作符. 为了使new
操作符在生成的Proxy
对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]
内部方法(即 new target
必须是有效的)。handler.construct()
必须返回一个对象,否则会报错。
2.1 语法
const proxy = new Proxy(target, {
construct(target, argumentsList, newTarget) {
}
});
-
target
: 目标对象 -
argumentsList
:constructor
的参数列表 -
newTarget
: 最初被调用的构造函数,就上面的例子而言是p
2.2 返回值
**construct
**方法必须返回一个对象
2.3 拦截场景
拦截new proxy(...args)
const proxy = new Proxy(function() {},{
construct:function(target,argumentsList,newTarget){
console.log(argumentsList.join(','));
return {}
}
});
const p = new proxy('a','b','c');
console.log(p);
三、handler.defineProperty()
**handler.defineProperty()
用于拦截对对象的Object.defineProperty()
**操作。
3.1 语法
const proxy = new Proxy(target, {
defineProperty(target, property, descriptor) {
}
});
-
target
: 目标对象 -
property
: 待检索其描述的属性名 -
descriptor
: 待定义或修改的属性的描述符
3.2 返回值
**defineProperty
方法必须以一个Boolean
**返回,表示定义该属性的操作成功与否。
3.3 拦截场景
拦截 Object.defineProperty()
const proxy = new Proxy({},{
defineProperty:function(target,prop,descriptor){
console.log(prop);
return true;
}
});
Object.defineProperty(proxy,'name',{
value:'柏拉图',
writable:true,
enumerable:true,
configurable:true
});
console.log(proxy);
const proxy = new Proxy({},{
defineProperty:function(target,prop,descriptor){
console.log(prop);
return Reflect.defineProperty(target,prop,descriptor);
}
});
Object.defineProperty(proxy,'name',{
value:'柏拉图',
writable:true,
enumerable:true,
configurable:true
});
四、handler.deleteProperty()
**handler.deleteProperty()
方法用于拦截对对象属性的delete
**操作。
4.1 语法
const proxy = new Proxy(target, {
deleteProperty: function(target, property) {
}
});
-
target
: 目标对象 -
property
: 待删除的属性名
4.2 返回值
**deleteProperty
**必须返回一个 Boolean
类型的值,表示了该属性是否被成功删除。
4.3 拦截场景
拦截Reflect.deleteProperty()
拦截delete proxy[foo]
和 delete proxy.foo
const proxy = new Proxy({},{
deleteProperty:function(target,prop){
console.log(prop);
return true;
}
});
delete proxy.a;
五、handler.get()
**handler.get()
**方法用于拦截对象的读取属性操作。
5.1 语法
const proxy = new Proxy(target, {
get: function(target, property, receiver) {
}
});
-
target
: 目标对象 -
property
: 被获取的属性名 -
receiver
: Proxy或者继承Proxy的对象(表示代理对象本身或者继承与代理对象的对象)。为了确保拦截器函数中正确的传递上下文访问
5.2 返回值
get
方法可以返回任何值。
5.3 拦截场景
拦截Reflect.get()
拦截 proxy[foo]和 proxy.bar
const proxy = new Proxy({},{
get:function(target,prop,receiver){
console.log(prop);
return 10
}
});
console.log(proxy.a);
拦截访问原型链上的属性: Object.create(proxy)[foo]
六、handler.getOwnPropertyDescriptor()
**handler.getOwnPropertyDescriptor()
方法是Object.getOwnPropertyDescriptor()
**的钩子
6.1 语法
const proxy = new Proxy(target, {
getOwnPropertyDescriptor: function(target, prop) {
}
});
-
target
: 目标对象 -
prop
: 返回属性名称的描述
6.2 返回值
**getOwnPropertyDescriptor
**方法必须返回一个 object
或 undefined
6.3 拦截场景
拦截Object.getOwnPropertyDescriptor()
const proxy = new Proxy({},{
getOwnPropertyDescriptor:function(target,prop){
console.log(prop);
return {value:'测试',writable:true,enumerable:true,configurable:true}
}
});
const result = Object.getOwnPropertyDescriptor(proxy,'a');
console.log(result)
七、handler.getPrototypeOf()
**handler.getPrototypeOf()
**是一个代理(Proxy
)方法,当读取代理对象的原型时,该方法就会被调用。
7.1 语法
const proxy = new Proxy(obj, {
getPrototypeOf(target) {
...
}
});
target
: 被代理的目标对象
7.2 返回值
getPrototypeOf
方法的返回值必须是一个对象或者 null
。
7.3 拦截场景
拦截__proto__
const proxy = new Proxy({},{
getPrototypeOf:function(target){
console.log(target);
return target;
}
});
console.log(proxy.__proto__);
拦截instanceof
拦截Object.getPrototypeOf()
拦截Reflect.getPrototypeOf()
拦截Object.prototype.isPrototypeOf()
八、handler.has()
**handler.has()
方法是针对in
**操作符的代理方法。
8.1 语法
const = new Proxy(target, {
has: function(target, prop) {
}
});
-
target
: 目标对象 -
prop
: 需要检查是否存在的属性
8.2 返回值
has
方法返回一个 boolean
属性的值.
8.3 拦截场景
拦截 foo in proxy
const proxy = new Proxy({},{
has(target,key){
return Reflect.has(target,key);
}
});
console.log('a' in proxy);
拦截 Reflect.has()
拦截 with(proxy) { (foo); }
拦截 foo in Object.create(proxy)
九、handler.isExtensible()
handler.isExtensible()
方法用于拦截对对象的Object.isExtensible()
。
9.1 语法
const proxy = new Proxy(target, {
isExtensible: function(target) {
}
});
target
: 目标对象
9.2 返回值
isExtensible
方法必须返回一个 Boolean
值或可转换成Boolean
的值。
9.3 拦截场景
拦截Object.isExtensible()
const proxy = new Proxy({},{
isExtensible:function(target){
console.log(target);
return true
}
});
Object.isExtensible(proxy);
拦截Reflect.isExtensible()
十、handler.ownKeys()
handler.ownKeys()
方法用于拦截Reflect.ownKeys()
10.1 语法
const proxy = new Proxy(target, {
ownKeys: function(target) {
}
});
target
: 目标对象.
10.2 返回值
ownKeys
方法必须返回一个可枚举对象.
10.3 拦截场景
拦截for……in
const proxy = new Proxy({},{
ownKeys(target){
return Reflect.ownKeys(target);
}
})
for(const key in proxy){
}
拦截Object.keys()
const proxy = new Proxy({},{
ownKeys:function(target){
console.log(target);
return ['a','b','c']
}
});
console.log(Object.getOwnPropertyNames(proxy));
拦截Reflect.ownKeys()
拦截Object.getOwnPropertyNames()
拦截Object.getOwnPropertySymbols()
十一、handler.preventExtensions()
handler.preventExtensions()
方法用于设置对**Object.preventExtensions()
**的拦截
11.1 语法
const proxy = new Proxy(target, {
preventExtensions: function(target) {
}
});
target
: 所要拦截的目标对象.
11.2 返回值
preventExtensions
方法返回一个布尔值.
11.3 拦截场景
拦截Object.preventExtensions()
const proxy = new Proxy({},{
preventExtensions:function(target){
console.log(target);
Reflect.preventExtensions(target);
return true;
}
});
console.log(Object.preventExtensions(proxy));
拦截Reflect.preventExtensions()
十二、handler.set()
**handler.set()
**方法是设置属性值操作的捕获器。
12.1 语法
const p = new Proxy(target, {
set: function(target, property, value, receiver) {
}
});
-
target
: 目标对象 -
property
: 将被设置的属性名或Symbol
。 -
value
: 新属性值 -
receiver
: 最初被调用的对象。通常是proxy
本身,但handler
的set
方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是proxy
本身)。
12.2 返回值
set()
方法应当返回一个布尔值。
-
返回
true
代表属性设置成功。 -
在严格模式下,如果
set()
方法返回false
,那么会抛出一个TypeError
异常。
12.3 拦截场景
拦截Reflect.set()
拦截 Object.create(proxy)[foo] = bar
拦截proxy[foo] = bar
和 proxy.foo = bar
十三、handler.setPrototypeOf()
handler.setPrototypeOf()
方法主要用来拦截 Object.setPrototypeOf()
.
13.1 语法
const proxy = new Proxy(target, {
setPrototypeOf: function(target, prototype) {
}
});
-
target
: 被拦截目标对象. -
prototype
: 对象新原型或为null
.
13.2 返回值
如果成功修改了[[Prototype]]
, setPrototypeO
f 方法返回 true
,否则返回 false
13.3 拦截场景
拦截Object.setPrototypeOf()
拦截Reflect.setPrototypeOf()