Proxy 代理对象
如果想要监视某个对象中属性的读写,可以使用 ECMAScript2015 之前的 Object.defineProperty()
方法为对象添加属性,这样的话就可以监测到对象属性的读写过程。这种方法应用的非常广泛,在 Vue3.0 之前的版本就是使用这样的方法来实现数据响应,从而完成双向数据绑定。
在 ECMAScript2015 当中设计了 Proxy
类型,它就是专门为对象设置访问代理器的。如果你不能理解什么是代理的话,你可以把它想象成门卫。也就是说,无论你是从里面拿东西还是放东西,都需要经过这样的一个代理。通过 Proxy
就可以轻松地监视到对象属性的读写过程。相对于 Object.defineProperty()
方法,Proxy
的功能更为强大,使用起来也更为方便。
接下来,就来看看 Proxy
的具体用法。首先,通过字面量方式来定义一个 person
对象。如下代码所示:
const person = {
name: '前端课湛',
age: 20
}
然后,通过 new Proxy()
方式为 person
对象创建一个代理对象。如下代码所示:
const personProxy = new Proxy(person, {
get() {
},
set() {
}
})
在上述代码中,Proxy
构造函数中接收了两个参数,第一个参数就是代理的目标对象,第二个参数也是一个对象,可以称之为代理的处理对象。
这个代理的处理对象中的 get()
方法可以用来监视属性的访问,set()
方法可以用来监视属性的设置。
接下来,先看 get()
方法,这个方法可以接收 target
和 property
两个参数,这个方法的返回值是作为外部访问这个属性所得到的结果。如下代码所示:
const personProxy = new Proxy(person, {
get(target, property) {
console.log(target, property)
return 100
},
set() {
}
})
console.log(personProxy.name)
上述代码的运行结果如下:
{
name: '前端课湛', age: 20 } name
100
从打印的结果可以看到,这时的 get()
方法已经监听到了属性的读取。其中 target
参数指的是代理的目标对象,property
参数指的是外部访问对象的属性名,而返回值就是访问属性之后所得到的结果。
get()
方法内部正常的逻辑应该是先来判断代理目标对象当中是否存在这样一个属性,如下代码所示:
const personProxy = new Proxy(person, {
get(target, property) {
return property in target ? target[property] : undefined
},
set() {
}
})
console.log(personProxy.name)
console.log(personProxy.xxx)
如果访问的属性存在的话,则返回该属性的值;如果不存在的话,则返回 undefined
或者提供的默认值。
然后,再来看一下 set()
方法,这个方法可以接收 target
、property
和 value
三个参数。如下代码所示:
const personProxy =