Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)。
语法:new Proxy(target, handler)
参数:
Proxy
包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)p
的行为Proxy.revocable()
方法可以用来创建一个可撤销的代理对象。
语法:Proxy.revocable(target, handler)
target
:将用 Proxy
封装的目标对象。可以是任何类型的对象,包括原生数组,函数,甚至可以是另外一个代理对象。handler
:一个对象,其属性是一批可选的函数,这些函数定义了对应的操作被执行时代理的行为。handler
对象是一个容纳一批特定属性的占位符对象。它包含有 Proxy
的各个捕获器(trap)。
所有的捕捉器是可选的。如果没有定义某个捕捉器,那么就会保留源对象的默认行为。
handler.get()
handler.get()
方法用于拦截对象的读取属性操作。
语法:
new Proxy(target, {
get(target, property, receiver) {},
});
参数:
target
:目标对象property
:被获取的属性名receiver
:Proxy 或者继承 Proxy 的对象返回:返回任何值
该方法会拦截目标对象的以下操作:
proxy[foo] 和
proxy.bar
Object.create(proxy)[foo]
Reflect.get()
如果违背了以下的约束,proxy 会抛出 TypeError
:
handler.set()
方法是设置属性值操作的捕获器。
语法:
new Proxy(target, {
set(target, property, value, receiver) {}
});
参数:
target
:目标对象property
:被获取的属性名receiver
:Proxy 或者继承 Proxy 的对象返回:返回一个布尔值
true
代表属性设置成功set()
方法返回 false
,那么会抛出一个 TypeError
异常该方法会拦截目标对象的以下操作:
proxy[foo] = bar
和 proxy.foo = bar
Object.create(proxy)[foo] = bar
Reflect.set()
如果违背以下的约束条件,proxy 会抛出一个 TypeError
异常:
[[Set]]
属性的是 undefined
,则不能设置它的值set()
方法返回 false
,那么也会抛出一个 TypeError
异常handler.has()
方法是针对 in
操作符的代理方法。
语法:
new Proxy(target, {
has(target, prop) {},
});
参数:
target
:目标对象prop
:需要检查是否存在的属性返回:返回一个 boolean 属性的值
这个钩子可以拦截下面这些操作:
foo in proxy
foo in Object.create(proxy)
with
检查: with(proxy) { (foo); }
Reflect.has()
如果违反了下面这些规则,proxy 将会抛出 TypeError
:
handler.apply()
方法用于拦截函数的调用。
语法:
new Proxy(target, {
apply(target, thisArg, argumentsList) {},
});
参数:
target
:目标对象(函数)thisArg
:被调用时的上下文对象argumentsList
:被调用时的参数数组返回:返回任何值
该方法会拦截目标对象的以下操作:
proxy(...args)
Function.prototype.apply()
和 Function.prototype.call()
Reflect.apply()
handler.construct()
方法用于拦截 new
操作符。为了使 new 操作符在生成的 Proxy 对象上生效,用于初始化代理的目标对象自身必须具有 [[Construct]] 内部方法(即 new target
必须是有效的)。
语法:
new Proxy(target, {
construct(target, argumentsList, newTarget) {},
});
参数:
target
:目标对象argumentsList
:constructor 的参数列表newTarget
:最初被调用的构造函数,就上面的例子而言是 p返回:返回一个对象
该拦截器可以拦截以下操作:
new proxy(...args)
Reflect.construct()
如果违反以下约定,代理将会抛出错误 TypeError
:
handler.deleteProperty()
方法用于拦截对对象属性的 delete
操作。
语法:
new Proxy(target, {
deleteProperty(target, property) {},
});
参数:
target
:目标对象property
:被获取的属性名返回:返回一个 Boolean
类型的值,表示了该属性是否被成功删除
该方法会拦截以下操作:
delete proxy[foo]
和 delete proxy.foo
Reflect.deleteProperty()
如果违背了以下不变量,proxy 将会抛出一个 TypeError
:
handler.ownKeys()
方法用于拦截 Reflect.ownKeys()
。
语法:
new Proxy(target, {
ownKeys(target) {},
});
参数:
target
:目标对象返回:返回一个可枚举对象
该拦截器可以拦截以下操作::
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
如果违反了下面的约束,proxy 将抛出错误 TypeError
:
ownKeys
的结果必须是一个数组String
,要么是一个 Symbol
handler.getPrototypeOf()
是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。
语法:
new Proxy(target, {
getPrototypeOf(target) {}
})
参数:
返回:返回一个对象或者 null
。
这个方法可以拦截以下操作:
Object.getPrototypeOf()
Reflect.getPrototypeOf()
Object.prototype.__proto__
Object.prototype.isPrototypeOf()
instanceof
如果遇到了下面情况,JS 引擎会抛出 TypeError
异常:
getPrototypeOf()
方法返回的不是对象也不是 null
getPrototypeOf()
方法返回的原型不是目标对象本身的原型handler.setPrototypeOf()
方法主要用来拦截 Object.setPrototypeOf()
.
语法:
new Proxy(target, {
setPrototypeOf(target, prototype) {}
})
参数:
target
:被拦截目标对象prototype
:对象新原型或为 null
返回:如果成功修改了[[Prototype]]
,返回 true
,否则返回 false
这个方法可以拦截以下操作:
Object.setPrototypeOf()
Reflect.setPrototypeOf()
如果遇到了下面情况,JS 引擎会抛出 TypeError
异常:
target
不可扩展,原型参数必须与 Object.getPrototypeOf(target)
的值相同handler.isExtensible()
方法用于拦截对对象的 Object.isExtensible()
。
语法:
new Proxy(target, {
isExtensible(target) {}
})
参数:
target
:目标对象返回:返回一个 Boolean 值或可转换成 Boolean 的值
这个方法可以拦截以下操作:
Object.isExtensible()
Reflect.isExtensible()
如果遇到了下面情况,JS 引擎会抛出 TypeError
异常:
Object.isExtensible(proxy)
必须同 Object.isExtensible(target)
返回相同值handler.preventExtensions()
方法用于设置对 Object.preventExtensions()
的拦截。
语法:
new Proxy(target, {
preventExtensions(target) {}
})
参数:
target
:所要拦截的目标对象返回:返回一个布尔值
这个方法可以拦截以下操作:
Object.preventExtensions()
Reflect.preventExtensions()
如果遇到了下面情况,JS 引擎会抛出 TypeError
异常:
handler.getOwnPropertyDescriptor()
方法是 Object.getOwnPropertyDescriptor()
的钩子。
语法:
new Proxy(target, {
getOwnPropertyDescriptor(target, prop) {}
})
参数:
target
:所要拦截的目标对象返回:返回一个 object 或 undefined
这个方法可以拦截以下操作:
Object.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor()
如果下列不变量被违反,代理将抛出一个 TypeError
:
getOwnPropertyDescriptor
必须返回一个 object 或 undefined
。handler.defineProperty()
用于拦截对象的 Object.defineProperty()
操作。
语法:
new Proxy(target, {
defineProperty(target, property, descriptor) {}
})
参数:
target
:目标对象property
:待检索其描述的属性名descriptor
:待定义或修改的属性的描述符返回:返回 Boolean
,表示定义该属性的操作成功与否
该方法会拦截目标对象的以下操作:
Object.defineProperty()
Reflect.defineProperty()
proxy.property='value'
如果违背了以下的不变量,proxy 会抛出 TypeError
:
Object.defineProperty(target, prop, descriptor)
将不会抛出异常false
作为 handler.defineProperty
方法的返回值的话将会抛出 TypeError
异常Reflect 是一个内置的对象,它提供拦截 JavaScript 操作的方法。这些方法与 proxy.handler 的方法相同。
Reflect
不是一个函数对象,因此它是不可构造的。