Proxy和Reflect详解

之前一直没有理解proxy代理是啥意思,只是感觉很深奥的样子,最近正好在研究vue3的响应式原理,发现vue3是使用proxy完成响应式的,因此仔细的研究了一下proxy和reflect到底是啥

proxy是es6新增的一个新特性,可以通过代理对象完成对目标对象的拦截,并在拦截后进行骚操作

Proxy是通过实例化来生成的,入参有两个,第一个target是要拦截的目标对象,handler处理程序对象是对拦截后要完成的操作

let target = {
	foo: '谢小虫虫'
}
let handler ={
	//target目标对象
	//property属性名
	//生成的代理对象
	get(target,property,receiver){
		return target[property] + '虫虫飞'
	}
}
// proxy实现了对目标对象的拦截,并修改了返回数据
const proxy = new Proxy(target,handler)
console.log(target.foo)  // 谢小虫虫
console.log(proxy.foo)  // 谢小虫虫虫虫飞

使用代理的主要目的是为了定义捕获器,捕获器就是类似上述handler处理程序对象中的get,简单来说就是在handler中定义的基本操作的拦截器
捕获器一共13种,每种捕获器都有不同的参数和捕获不变式(捕获器必须遵守的一些行为)
apply 、construct、defineProperty、deleteProperty、get、getOwnPropertyDescriptor、getPrototypeOf、has、isExtensible
ownKeys、preventExtensions、set、setPrototypeOf

并非所有捕获器行为都像get那么简单,为了简化操作,我们可以直接调用全局Reflect,Reflect反射是在一个在全局中定义好的,包含了上述方法的对象,我们可以轻松通过同名方法重建

以上例子使用reflect后的效果,虽然在get中看不出什么效果,但用在较为复杂的捕获其上能简化很多

let target = {
	foo: '谢小虫虫'
}
let handler ={
	//target目标对象
	//property属性名
	//生成的代理对象
	get(target,property,receiver){
		return Reflect.get(...arguments)+ '虫虫飞'
	}
}
// proxy实现了对目标对象的拦截,并修改了返回数据
const proxy = new Proxy(target,handler)
console.log(target.foo)  // 谢小虫虫
console.log(proxy.foo)  // 谢小虫虫虫虫飞

甚至我们可以使用Reflect直接一次性设置代理中的所有捕获器

let target = {
	foo: '谢小虫虫'
}
const proxy = new Proxy(target,Reflect)

可撤销代理

某些情况下我们需要中断代理对象与目标对象之间的联系,我们可以使用Proxy的revocable()方法

let target = {
	foo: '谢小虫虫'
}
let handler ={
	get(target,property,receiver){
		return target[property] + '虫虫飞'
	}
}
//代理对象与撤销函数是在实例化的时候同时生成的
const {proxy,revoke} = Proxy.revocable(target,Reflect)
console.log(proxy.foo) // 谢小虫虫虫虫飞
revoke()
console.log(proxy.foo)  // TypeError
Logo

前往低代码交流专区

更多推荐